home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / portage / bin / emerge < prev    next >
Encoding:
Text File  |  2006-06-30  |  119.5 KB  |  3,536 lines

  1. #!/usr/bin/python -O
  2. # Copyright 1999-2006 Gentoo Foundation
  3. # Distributed under the terms of the GNU General Public License v2
  4. # $Id: /var/cvsroot/gentoo-src/portage/bin/emerge,v 1.345.2.38 2005/08/13 17:25:26 ferringb Exp $
  5.  
  6. import os,sys
  7. os.environ["PORTAGE_CALLER"]="emerge"
  8. sys.path = ["/usr/lib/portage/pym"]+sys.path
  9. import errno
  10.  
  11. try:
  12.     import portage
  13. except KeyboardInterrupt:
  14.     sys.exit(1) # If they control C during imports, just die silently
  15.  
  16. import emergehelp,xpak,string,re,commands,time,shutil,traceback,signal,socket,types
  17. from stat import *
  18. from output import *
  19.  
  20. import portage_util
  21. import portage_locks
  22. import portage_exception
  23. from portage_const import PROFILE_PATH
  24.  
  25. portage.global_updates(
  26.     portage.settings, portage.db, portage.mtimedb["updates"])
  27.  
  28. spinner_msgs = ["Gentoo Rocks ("+os.uname()[0]+")",
  29.                 "Thank you for using Gentoo. :)",
  30.                 "Are you actually trying to read this?",
  31.                 "How many times have you stared at this?",
  32.                 "We are generating the cache right now",
  33.                 "You are paying too much attention.",
  34.                 "A theory is better than its explanation.",
  35.                 "Phasers locked on target, Captain.",
  36.                 "Thrashing is just virtual crashing.",
  37.                 "To be is to program.",
  38.                 "Real Users hate Real Programmers.",
  39.                 "When all else fails, read the instructions.",
  40.                 "Functionality breeds Contempt.",
  41.                 "The future lies ahead.",
  42.                 "3.1415926535897932384626433832795028841971694",
  43.                 "Sometimes insanity is the only alternative.",
  44.                 "Inaccuracy saves a world of explanation.",
  45.                ]
  46.  
  47.  
  48. def update_basic_spinner():
  49.     global spinner, spinpos
  50.     spinpos = (spinpos+1) % 500
  51.     if (spinpos % 100) == 0:
  52.         if spinpos == 0:
  53.             sys.stdout.write(". ")
  54.         else:
  55.             sys.stdout.write(".")
  56.     sys.stdout.flush()
  57.  
  58. def update_scroll_spinner():
  59.     global spinner, spinpos
  60.     if(spinpos >= len(spinner)):
  61.         sys.stdout.write(darkgreen(" \b\b\b"+spinner[len(spinner)-1-(spinpos%len(spinner))]))
  62.     else:
  63.         sys.stdout.write(green("\b "+spinner[spinpos]))
  64.     sys.stdout.flush()
  65.     spinpos = (spinpos+1) % (2*len(spinner))
  66.  
  67. def update_twirl_spinner():
  68.     global spinner, spinpos
  69.     spinpos = (spinpos+1) % len(spinner)
  70.     sys.stdout.write("\b\b "+spinner[spinpos])
  71.     sys.stdout.flush()
  72.  
  73. def update_quiet_spinner():
  74.     return
  75.  
  76. spinpos = 0
  77. spinner = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|"
  78. update_spinner = update_twirl_spinner
  79. if "candy" in portage.settings.features:
  80.     spinner = spinner_msgs[int(time.time()*100)%len(spinner_msgs)]
  81.     update_spinner = update_scroll_spinner
  82.  
  83. # To enhance usability, make some vars case insensitive by forcing them to
  84. # lower case.
  85. portage.settings.unlock()
  86. for myvar in ("AUTOCLEAN", "NOCOLOR"):
  87.     if myvar in portage.settings:
  88.         portage.settings[myvar] = portage.settings[myvar].lower()
  89.         portage.settings.backup_changes(myvar)
  90. portage.settings.lock()
  91. del myvar
  92.  
  93. if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes","true"]):
  94.     nocolor()
  95.  
  96.  
  97.  
  98. def normpath(mystr):
  99.     """ 
  100.         os.path.normpath("//foo") returns "//foo" instead of "/foo"
  101.         We dislike this behavior so we create our own normpath func
  102.         to fix it.
  103.     """
  104.     if mystr and (mystr[0]=='/'):
  105.         return os.path.normpath("///"+mystr)
  106.     else:
  107.         return os.path.normpath(mystr)
  108.  
  109. def userquery(prompt, responses=None, colours=None):
  110.     """Displays a prompt and a set of responses, then waits for a response
  111.     which is checked against the responses and the first to match is
  112.     returned.  An empty response will match the first value in responses.  The
  113.     input buffer is *not* cleared prior to the prompt!
  114.  
  115.     prompt: a String.
  116.     responses: a List of Strings.
  117.     colours: a List of Functions taking and returning a String, used to
  118.     process the responses for display. Typically these will be functions
  119.     like red() but could be e.g. lambda x: "DisplayString".
  120.     If responses is omitted, defaults to ["Yes", "No"], [green, red].
  121.     If only colours is omitted, defaults to [bold, ...].
  122.  
  123.     Returns a member of the List responses. (If called without optional
  124.     arguments, returns "Yes" or "No".)
  125.     KeyboardInterrupt is converted to SystemExit to avoid tracebacks being
  126.     printed."""
  127.     if responses is None:
  128.         responses, colours = ["Yes", "No"], [green, red]
  129.     elif colours is None:
  130.         colours=[bold]
  131.     colours=(colours*len(responses))[:len(responses)]
  132.     print bold(prompt),
  133.     try:
  134.         while True:
  135.             response=raw_input("["+string.join([colours[i](responses[i]) for i in range(len(responses))],"/")+"] ")
  136.             for key in responses:
  137.                 # An empty response will match the first value in responses.
  138.                 if response.upper()==key[:len(response)].upper():
  139.                     return key
  140.             print "Sorry, response '%s' not understood." % response,
  141.     except (EOFError, KeyboardInterrupt):
  142.         print "Interrupted."
  143.         sys.exit(1)
  144.  
  145. def sorted_versions(verlist):
  146.     ret = []
  147.     for ver in verlist:
  148.         verparts = ver.split("-")
  149.         if len(verparts) == 2:
  150.             verrev = int(verparts[1][1:])
  151.         else:
  152.             verrev = 0
  153.         x = 0
  154.         while x < len(ret):
  155.             retparts = ret[x].split("-")
  156.             verdiff = portage.vercmp(retparts[0], verparts[0])
  157.             if verdiff > 0:
  158.                 break
  159.             elif verdiff == 0:
  160.                 if len(retparts) == 2:
  161.                     retrev = int(retparts[1][1:])
  162.                 else:
  163.                     retrev = 0
  164.                 if retrev >= verrev:
  165.                     break
  166.             x += 1
  167.         ret.insert(x, ver)
  168.     return ret
  169.  
  170. portage.deprecated_profile_check()
  171.  
  172. if portage.settings.has_key("PORTAGE_NICENESS"):
  173.     try:
  174.         os.nice(int(portage.settings["PORTAGE_NICENESS"]))
  175.     except (OSError,ValueError), e:
  176.         print "!!! Failed to change nice value to '"+str(portage.settings["PORTAGE_NICENESS"])+"'"
  177.         print "!!!",e
  178.  
  179. #Freeze the portdbapi for enhanced performance:
  180. portage.portdb.freeze()
  181.  
  182. # Kill noauto as it will break merges otherwise.
  183. if "noauto" in portage.settings.features:
  184.     while "noauto" in portage.settings.features:
  185.         portage.settings.features.remove("noauto")
  186.     portage.settings.unlock()
  187.     portage.settings["FEATURES"] = " ".join(portage.settings.features)
  188.     portage.settings.backup_changes("FEATURES")
  189.     portage.settings.lock()
  190.  
  191. #number of ebuilds merged
  192. merged=0
  193. params=["selective", "deep", "self", "recurse", "empty"]
  194. actions=[
  195. "clean", "config", "depclean",
  196. "info", "metadata",
  197. "prune", "regen",  "search",
  198. "sync",  "system", "unmerge",  "world",
  199. ]
  200. options=[
  201. "--ask",          "--alphabetical",
  202. "--buildpkg",     "--buildpkgonly",
  203. "--changelog",    "--columns", "--cols",
  204. "--debug",        "--deep",
  205. "--digest",
  206. "--emptytree",
  207. "--fetchonly",    "--fetch-all-uri",
  208. "--getbinpkg",    "--getbinpkgonly",
  209. "--help",         "--ignore-default-opts",
  210. "--noconfmem",
  211. "--newuse",       "--nocolor",
  212. "--nodeps",       "--noreplace",
  213. "--nospinner",    "--oneshot",
  214. "--onlydeps",     "--pretend",
  215. "--quiet",        "--resume",
  216. "--searchdesc",   "--selective",
  217. "--skipfirst",    "--skip-first",
  218. "--tree",
  219. "--update",       
  220. "--usepkg",       "--usepkgonly",
  221. "--verbose",      "--version"
  222. ]
  223.  
  224. shortmapping={
  225. "1":"--oneshot",
  226. "a":"--ask",
  227. "b":"--buildpkg",  "B":"--buildpkgonly",
  228. "c":"--clean",     "C":"--unmerge",
  229. "d":"--debug",     "D":"--deep",
  230. "e":"--emptytree",
  231. "f":"--fetchonly", "F":"--fetch-all-uri",
  232. "g":"--getbinpkg", "G":"--getbinpkgonly",
  233. "h":"--help",
  234. "k":"--usepkg",    "K":"--usepkgonly",
  235. "l":"--changelog",
  236. "n":"--noreplace", "N":"--newuse",
  237. "o":"--onlydeps",  "O":"--nodeps",
  238. "p":"--pretend",   "P":"--prune",
  239. "q":"--quiet",
  240. "s":"--search",    "S":"--searchdesc",
  241. 't':"--tree",
  242. "u":"--update",
  243. "v":"--verbose",   "V":"--version"
  244. }
  245.  
  246. myaction=None
  247. myopts=[]
  248. myfiles=[]
  249. edebug=0
  250.  
  251. # process short actions
  252. tmpcmdline=sys.argv[1:]
  253. if "--ignore-default-opts" not in tmpcmdline:
  254.     tmpcmdline.extend(portage.settings["EMERGE_DEFAULT_OPTS"].split())
  255. cmdline=[]
  256. for x in tmpcmdline:
  257.     if x[0:1]=="-" and x[1:2]!="-":
  258.         for y in x[1:]:
  259.             if shortmapping.has_key(y):
  260.                 if shortmapping[y] in cmdline:
  261.                     print
  262.                     print "*** Warning: Redundant use of",shortmapping[y]
  263.                 else:
  264.                     cmdline.append(shortmapping[y])
  265.             else:
  266.                 print "!!! Error: -"+y+" is an invalid short action or option."
  267.                 sys.exit(1)
  268.     else:
  269.         cmdline.append(x)
  270.  
  271. # process the options and command arguments
  272. for x in cmdline:
  273.     if not x:
  274.         continue
  275.     if len(x)>=2 and x[0:2]=="--":
  276.         if x == "--cols":
  277.             x = "--columns"
  278.         elif x == "--skip-first":
  279.             x = "--skipfirst"
  280.         if x in options:
  281.             if x not in myopts:
  282.                 myopts.append(x)
  283.         elif x[2:] in actions:
  284.             if myaction:
  285.                 if myaction not in ["system", "world"]:
  286.                     myaction="--"+myaction
  287.                 print
  288.                 print red("!!!")+green(" Multiple actions requested... Please choose one only.")
  289.                 print red("!!!")+" '"+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
  290.                 print
  291.                 sys.exit(1)
  292.             myaction=x[2:]
  293.         else:
  294.             print "!!! Error:",x,"is an invalid option."
  295.             sys.exit(1)
  296.     elif (not myaction) and (x in actions):
  297.         if x not in ["system", "world"]:
  298.             print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
  299.         if myaction:
  300.             print
  301.             print red("!!!")+green(" Multiple actions requested... Please choose one only.")
  302.             print red("!!! '")+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
  303.             print
  304.             sys.exit(1)
  305.         myaction=x
  306.     elif x[-1]=="/":
  307.         # this little conditional helps tab completion
  308.         myfiles.append(x[:-1])
  309.     else:
  310.         myfiles.append(x)
  311.  
  312.  
  313. if "moo" in myfiles:
  314.     print """
  315.  
  316.   Larry loves Gentoo (""" + os.uname()[0] + """)
  317.  
  318.  _______________________
  319. < Have you mooed today? >
  320.  -----------------------
  321.         \   ^__^
  322.          \  (oo)\_______
  323.             (__)\       )\/\ 
  324.                 ||----w |
  325.                 ||     ||
  326.  
  327. """
  328.  
  329. if (myaction in ["world", "system"]) and myfiles:
  330.     print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both."
  331.     sys.exit(1)
  332.  
  333. for x in myfiles:
  334.     ext = os.path.splitext(x)[1]
  335.     if (ext == ".ebuild" or ext == ".tbz2") and os.path.exists(os.path.abspath(x)):
  336.         print "emerging by path implies --oneshot... adding --oneshot to options."
  337.         print red("\n*** emerging by path is broken and may not always work!!!\n")
  338.         break
  339.  
  340. if ("--tree" in myopts) and ("--columns" in myopts):
  341.     print "emerge: can't specify both of \"--tree\" and \"--columns\"."
  342.     sys.exit(1)
  343.  
  344. if ("--quiet" in myopts):
  345.     update_spinner = update_quiet_spinner
  346.     portage_util.noiselimit = -1
  347.     portage.settings.unlock()
  348.     portage.settings["PORTAGE_QUIET"]="1"
  349.     portage.settings.backup_changes("PORTAGE_QUIET")
  350.     portage.settings.lock()
  351.  
  352. # Always create packages if FEATURES=buildpkg
  353. # Imply --buildpkg if --buildpkgonly
  354. if ("buildpkg" in portage.settings.features) or ("--buildpkgonly" in myopts):
  355.     if "--buildpkg" not in myopts:
  356.         myopts.append("--buildpkg")
  357.  
  358. # --tree only makes sense with --pretend
  359. if "--tree" in myopts and not (("--pretend" in myopts) or ("--ask" in myopts)):
  360.     print ">>> --tree implies --pretend... adding --pretend to options."
  361.     myopts.append("--pretend")
  362.  
  363. # Also allow -S to invoke search action (-sS)
  364. if ("--searchdesc" in myopts):
  365.     if myaction and myaction != "search":
  366.         myfiles.append(myaction)
  367.     if "--search" not in myopts:
  368.         myopts.append("--search")
  369.     myaction = "search"
  370.  
  371. # Always try and fetch binary packages if FEATURES=getbinpkg
  372. if ("getbinpkg" in portage.settings.features):
  373.     myopts.append("--getbinpkg")
  374.  
  375. if "--skipfirst" in myopts and "--resume" not in myopts:
  376.     myopts.append("--resume")
  377.  
  378. if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts):
  379.     myopts.append("--usepkgonly")
  380.  
  381. if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts):
  382.     myopts.append("--getbinpkg")
  383.  
  384. if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts):
  385.     myopts.append("--usepkg")
  386.  
  387. # Also allow -K to apply --usepkg/-k
  388. if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts):
  389.     myopts.append("--usepkg")
  390.  
  391. if ("--newuse" in myopts) and not ("--update" in myopts):
  392.     print ">>> --newuse implies --update... adding --update to options."
  393.     myopts.append("--update")
  394.  
  395. # Also allow -l to apply --pretend/-p, but if already in --ask mode
  396. if ("--changelog" in myopts) and not (("--pretend" in myopts) or ("--ask" in myopts)):
  397.     print ">>> --changelog implies --pretend... adding --pretend to options."
  398.     myopts.append("--pretend")
  399.  
  400. # Allow -p to remove --ask
  401. if ("--pretend" in myopts) and ("--ask" in myopts):
  402.     print ">>> --pretend disables --ask... removing --ask from options."
  403.     myopts.remove("--ask")
  404.  
  405. # forbid --ask when not in a terminal
  406. # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway.
  407. if ("--ask" in myopts) and (not sys.stdin.isatty()):
  408.     portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n",
  409.         noiselevel=-1)
  410.     sys.exit(1)
  411.  
  412. # Set so that configs will be merged regardless of remembered status
  413. if ("--noconfmem" in myopts):
  414.     portage.settings.unlock()
  415.     portage.settings["NOCONFMEM"]="1"
  416.     portage.settings.backup_changes("NOCONFMEM")
  417.     portage.settings.lock()
  418.  
  419. # Set various debug markers... They should be merged somehow.
  420. if ("--debug" in myopts):
  421.     portage.settings.unlock()
  422.     portage.settings["PORTAGE_DEBUG"]="1"
  423.     portage.settings.backup_changes("PORTAGE_DEBUG")
  424.     portage.debug=1
  425.     portage.settings.lock()
  426.     if "python-trace" in portage.settings.features:
  427.         import portage_debug
  428.         portage_debug.set_trace(True)
  429.  
  430. if ("--resume" in myopts):
  431.     if "--tree" in myopts:
  432.         print "* --tree is currently broken with --resume. Disabling..."
  433.         myopts.remove("--tree")
  434.  
  435. # Set color output
  436. if "--nocolor" in myopts or \
  437. portage.settings["NOCOLOR"] in ("yes","true"):
  438.     nocolor()
  439.     if "NOCOLOR" not in portage.settings:
  440.         portage.settings.unlock()
  441.         portage.settings["NOCOLOR"] = "true"
  442.         portage.settings.backup_changes("NOCOLOR")
  443.         portage.settings.lock()
  444.  
  445. if not ("--quiet" in myopts):
  446.     if not sys.stdout.isatty() or ("--nospinner" in myopts):
  447.         update_spinner = update_basic_spinner
  448.  
  449. CLEAN_DELAY = 5
  450. EMERGE_WARNING_DELAY = 10
  451. if portage.settings["CLEAN_DELAY"]:
  452.     CLEAN_DELAY = string.atoi("0"+portage.settings["CLEAN_DELAY"])
  453. if portage.settings["EMERGE_WARNING_DELAY"]:
  454.     EMERGE_WARNING_DELAY = string.atoi("0"+portage.settings["EMERGE_WARNING_DELAY"])
  455.  
  456. def emergelog(mystr,short_msg=None):
  457.     if "notitles" not in portage.settings.features:
  458.         if short_msg:
  459.             xtermTitle(short_msg)
  460.         else:
  461.             xtermTitle(mystr)
  462.     try:
  463.         #seems odd opening a file each write...
  464.         if not os.path.exists("/var/log/emerge.log"):
  465.             mylogfile=open("/var/log/emerge.log", "w")
  466.             os.chmod("/var/log/emerge.log", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
  467.             os.chown("/var/log/emerge.log", portage.portage_uid, portage.portage_gid)
  468.         else:
  469.             mylogfile=open("/var/log/emerge.log", "a")
  470.  
  471.         l=portage_locks.lockfile(mylogfile)
  472.         # seek because we may have gotten held up by the lock.
  473.         # if so, we may not be positioned at the end of the file.
  474.         mylogfile.seek(0,2)
  475.         mylogfile.write(str(time.time())[:10]+": "+mystr+"\n")
  476.         mylogfile.flush()
  477.         portage_locks.unlockfile(l)
  478.         mylogfile.close()
  479.     except (IOError,OSError,portage_exception.PortageException), e:
  480.         if edebug:
  481.             print "emergelog():",e
  482.         pass
  483.  
  484. def emergeexit():
  485.     """This gets out final log message in before we quit."""
  486.     if "--pretend" not in myopts:
  487.         emergelog(" *** terminating.")
  488.     if "notitles" not in portage.settings.features:
  489.         xtermTitleReset()
  490. portage.atexit_register(emergeexit)
  491.  
  492. def emergeexitsig(signum, frame):
  493.     signal.signal(signal.SIGINT, signal.SIG_IGN)
  494.     portage.portageexit()
  495.     portage_util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum})
  496.     sys.exit(100+signum)
  497. signal.signal(signal.SIGINT, emergeexitsig)
  498.  
  499. def countdown(secs=5, doing="Starting"):
  500.     if secs:
  501.         print ">>> Waiting",secs,"seconds before starting..."
  502.         print ">>> (Control-C to abort)...\n"+doing+" in: ",
  503.         ticks=range(secs)
  504.         ticks.reverse()
  505.         for sec in ticks:
  506.             sys.stdout.write(red(str(sec+1)+" "))
  507.             sys.stdout.flush()
  508.             time.sleep(1)
  509.         print
  510.  
  511. # formats a size given in bytes nicely
  512. def format_size(mysize):
  513.     if type(mysize) not in [types.IntType,types.LongType]:
  514.         return str(mysize)
  515.     mystr=str(mysize/1024)
  516.     mycount=len(mystr)
  517.     while (mycount > 3):
  518.         mycount-=3
  519.         mystr=mystr[:mycount]+","+mystr[mycount:]
  520.     return mystr+" kB"
  521.  
  522.  
  523. def getgccversion():
  524.     """
  525.     rtype: C{str}
  526.     return:  the current in-use gcc version
  527.     """
  528.  
  529.     gcc_ver_command = 'gcc -dumpversion'
  530.     gcc_ver_prefix = 'gcc-'
  531.  
  532.     gcc_not_found_error = red(
  533.     "!!! No gcc found. You probably need to 'source /etc/profile'\n" +
  534.     "!!! to update the environment of this terminal and possibly\n" +
  535.     "!!! other terminals also.\n"
  536.     )
  537.  
  538.     mystatus, myoutput = commands.getstatusoutput("eselect compiler show")
  539.     if mystatus == os.EX_OK and len(myoutput.split("/")) == 2:
  540.         part1, part2 = myoutput.split("/")
  541.         if len(part1.split("-")) > 0:
  542.             return gcc_ver_prefix + part1.split("-")[-1] + "/" + part2
  543.  
  544.     mystatus, myoutput = commands.getstatusoutput("gcc-config -c")
  545.     if mystatus == os.EX_OK and len(myoutput.split("-")) > 0:
  546.         return gcc_ver_prefix + myoutput.split("-")[-1]
  547.  
  548.     mystatus, myoutput = commands.getstatusoutput(
  549.         portage.settings["CHOST"] + "-" + gcc_ver_command)
  550.     if mystatus == os.EX_OK:
  551.         return gcc_ver_prefix + myoutput
  552.  
  553.     mystatus, myoutput = commands.getstatusoutput(gcc_ver_command)
  554.     if mystatus == os.EX_OK:
  555.         return gcc_ver_prefix + myoutput
  556.  
  557.     portage.writemsg(gcc_not_found_error, noiselevel=-1)
  558.     return "[unavailable]"
  559.  
  560. def getportageversion():
  561.     try:
  562.         import re
  563.         profilever = os.path.normpath("///"+os.readlink(PROFILE_PATH))
  564.         basepath   = os.path.normpath("///"+portage.settings["PORTDIR"]+"/profiles")
  565.         if re.match(basepath,profilever):
  566.             profilever = profilever[len(basepath)+1:]
  567.         else:
  568.             profilever = "!"+profilever
  569.         del basepath
  570.     except (OSError,IOError):
  571.         profilever="unavailable"
  572.     libcver=[]
  573.     libclist  = portage.vardbapi(portage.root).match("virtual/libc")
  574.     libclist += portage.vardbapi(portage.root).match("virtual/glibc")
  575.     libclist  = portage_util.unique_array(libclist)
  576.     for x in libclist:
  577.         xs=portage.catpkgsplit(x)
  578.         if libcver:
  579.             libcver+=","+string.join(xs[1:], "-")
  580.         else:
  581.             libcver=string.join(xs[1:], "-")
  582.     if libcver==[]:
  583.         libcver="unavailable"
  584.  
  585.     gccver = getgccversion()
  586.     unameout=os.uname()[2]+" "+os.uname()[4]
  587.  
  588.     return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", "+libcver+", "+unameout+")"
  589.  
  590. def help():
  591.     # Move all the help stuff out of this file.
  592.     emergehelp.help(myaction,myopts,havecolor)
  593.  
  594. if "--version" in myopts:
  595.     print getportageversion()
  596.     sys.exit(0)
  597. elif "--help" in myopts:
  598.     help()
  599.     sys.exit(0)
  600.  
  601. if portage.wheelgid == portage.portage_gid:
  602.     print "emerge: wheel group use is being deprecated. Please update group and passwd to"
  603.     print "        include the portage user as noted above, and then use group portage."
  604.  
  605. if "--debug" in myopts:
  606.     print "myaction", myaction
  607.     print "myopts", myopts
  608.  
  609. if not myaction and not myfiles and "--resume" not in myopts:
  610.     help()
  611.     sys.exit(1)
  612.  
  613. # check if root user is the current user for the actions where emerge needs this
  614. if portage.secpass < 2:
  615.     # We've already allowed "--version" and "--help" above.
  616.     if "--pretend" not in myopts and \
  617.     myaction not in ("search","info"):
  618.         if portage.secpass >= 1:
  619.             if "--fetchonly" not in myopts and \
  620.             "--fetch-all-uri" not in myopts and \
  621.             myaction not in ("metadata", "regen"):
  622.                 print "emerge: root access required."
  623.                 sys.exit(1)
  624.         else:
  625.             print "emerge: root access required."
  626.             sys.exit(1)
  627.  
  628. if not "--pretend" in myopts:
  629.     emergelog("Started emerge on: "+time.strftime("%b %d, %Y %H:%M:%S", time.localtime()))
  630.     myelogstr=""
  631.     if myopts:
  632.         myelogstr=string.join(myopts, " ")
  633.     if myaction:
  634.         myelogstr+=" "+myaction
  635.     if myfiles:
  636.         myelogstr+=" "+string.join(myfiles, " ")
  637.     emergelog(" *** emerge "+myelogstr)
  638.  
  639. #configure emerge engine parameters
  640. #
  641. # self:      include _this_ package regardless of if it is merged.
  642. # selective: exclude the package if it is merged
  643. # recurse:   go into the dependencies
  644. # empty:     pretend nothing is merged
  645. myparams=["self","recurse"]
  646. add=[]
  647. sub=[]
  648. if "--update" in myopts or myaction in ("system", "world"):
  649.     add.extend(["selective","empty"])
  650. if "--emptytree" in myopts:
  651.     add.extend(["empty"])
  652.     sub.extend(["selective"])
  653. if "--nodeps" in myopts:
  654.     sub.extend(["recurse"])
  655. if "--noreplace" in myopts:
  656.     add.extend(["selective"])
  657. if "--deep" in myopts:
  658.     add.extend(["deep"])
  659. if "--selective" in myopts:
  660.     add.extend(["selective"])
  661. if myaction in ["world","system"]:
  662.     add.extend(["selective"])
  663. elif myaction in ["depclean"]:
  664.     add.extend(["empty"])
  665.     sub.extend(["selective"])
  666. for x in add:
  667.     if (x not in myparams) and (x not in sub):
  668.         myparams.append(x)
  669. for x in sub:
  670.     if x in myparams:
  671.         myparams.remove(x)
  672.  
  673. # search functionality
  674. class search:
  675.  
  676.     #
  677.     # class constants
  678.     #
  679.     VERSION_SHORT=1
  680.     VERSION_RELEASE=2
  681.  
  682.     #
  683.     # public interface
  684.     #
  685.     def __init__(self):
  686.         """Searches the available and installed packages for the supplied search key.
  687.         The list of available and installed packages is created at object instantiation.
  688.         This makes successive searches faster."""
  689.         self.installcache = portage.db["/"]["vartree"]
  690.  
  691.     def execute(self,searchkey):
  692.         """Performs the search for the supplied search key"""
  693.         global myopts
  694.         match_category = 0
  695.         self.searchkey=searchkey
  696.         self.packagematches = []
  697.         if "--searchdesc" in myopts:
  698.             self.searchdesc=1
  699.             self.matches = {"pkg":[], "desc":[]}
  700.         else:
  701.             self.searchdesc=0
  702.             self.matches = {"pkg":[]}
  703.         print "Searching...   ",
  704.  
  705.         if self.searchkey[0] == '@':
  706.             match_category = 1
  707.             self.searchkey = self.searchkey[1:]
  708.         if self.searchkey=="*":
  709.             #hack for people who aren't regular expression gurus
  710.             self.searchkey==".*"
  711.         if re.search("\+\+", self.searchkey):
  712.             #hack for people who aren't regular expression gurus
  713.             self.searchkey=re.sub("\+\+","\+\+",self.searchkey)
  714.         self.searchre=re.compile(self.searchkey.lower(),re.I)
  715.         for package in portage.portdb.cp_all():
  716.             update_spinner()
  717.  
  718.             if match_category:
  719.                 match_string  = package[:]
  720.             else:
  721.                 match_string  = package.split("/")[-1]
  722.  
  723.             masked=0
  724.             if self.searchre.search(match_string):
  725.                 if not portage.portdb.xmatch("match-visible",package):
  726.                     masked=1
  727.                 self.matches["pkg"].append([package,masked])
  728.             elif self.searchdesc: # DESCRIPTION searching
  729.                 full_package = portage.portdb.xmatch("bestmatch-visible",package)
  730.                 if not full_package:
  731.                     #no match found; we don't want to query description
  732.                     full_package=portage.best(portage.portdb.xmatch("match-all",package))
  733.                     if not full_package:
  734.                         continue
  735.                     else:
  736.                         masked=1
  737.                 try:
  738.                     full_desc = portage.portdb.aux_get(full_package,["DESCRIPTION"])[0]
  739.                 except KeyError:
  740.                     print "emerge: search: aux_get() failed, skipping"
  741.                     continue
  742.                 if self.searchre.search(full_desc):
  743.                     self.matches["desc"].append([full_package,masked])
  744.         self.mlen=0
  745.         for mtype in self.matches.keys():
  746.             self.matches[mtype].sort()
  747.             self.mlen += len(self.matches[mtype])
  748.  
  749.     def output(self):
  750.         """Outputs the results of the search."""
  751.         print "\b\b  \n[ Results for search key : "+white(self.searchkey)+" ]"
  752.         print "[ Applications found : "+white(str(self.mlen))+" ]"
  753.         print " "
  754.         for mtype in self.matches.keys():
  755.             for match,masked in self.matches[mtype]:
  756.                 if mtype=="pkg":
  757.                     catpack=match
  758.                     full_package = portage.portdb.xmatch("bestmatch-visible",match)
  759.                     if not full_package:
  760.                         #no match found; we don't want to query description
  761.                         masked=1
  762.                         full_package=portage.best(portage.portdb.xmatch("match-all",match))
  763.                 else:
  764.                     full_package = match
  765.                     match        = portage.pkgsplit(match)[0]
  766.  
  767.                 if full_package:
  768.                     try:
  769.                         desc, homepage, license = portage.portdb.aux_get(full_package,["DESCRIPTION","HOMEPAGE","LICENSE"])
  770.                     except KeyError:
  771.                         print "emerge: search: aux_get() failed, skipping"
  772.                         continue
  773.                     if masked:
  774.                         print green("*")+"  "+white(match)+" "+red("[ Masked ]")
  775.                     else:
  776.                         print green("*")+"  "+white(match)
  777.                     myversion = self.getVersion(full_package, search.VERSION_RELEASE)
  778.  
  779.                     mysum = [0,0]
  780.                     mycat = match.split("/")[0]
  781.                     mypkg = match.split("/")[1]
  782.                     mycpv = match + "-" + myversion
  783.                     myebuild = portage.portdb.findname(mycpv)
  784.                     pkgdir = os.path.dirname(myebuild)
  785.                     import portage_manifest
  786.                     mf = portage_manifest.Manifest(
  787.                         pkgdir, portage.settings["DISTDIR"])
  788.                     fetchlist = portage.portdb.getfetchlist(mycpv,
  789.                         mysettings=portage.settings, all=True)[1]
  790.                     try:
  791.                         mysum[0] = mf.getDistfilesSize(fetchlist)
  792.                         mystr = str(mysum[0]/1024)
  793.                         mycount=len(mystr)
  794.                         while (mycount > 3):
  795.                             mycount-=3
  796.                             mystr=mystr[:mycount]+","+mystr[mycount:]
  797.                         mysum[0]=mystr+" kB"
  798.                     except KeyError, e:
  799.                         mysum[0] = "Unknown (missing digest for %s)" % str(e)
  800.  
  801.                     if "--quiet" not in myopts:
  802.                         print "     ", darkgreen("Latest version available:"),myversion
  803.                         print "     ", self.getInstallationStatus(mycat+'/'+mypkg)
  804.                         print "     ", darkgreen("Size of files:"),mysum[0]
  805.                         print "     ", darkgreen("Homepage:")+"     ",homepage
  806.                         print "     ", darkgreen("Description:")+"  ",desc
  807.                         print "     ", darkgreen("License:")+"      ",license
  808.                         print
  809.         print
  810.     #
  811.     # private interface
  812.     #
  813.     def getInstallationStatus(self,package):
  814.         installed_package = self.installcache.dep_bestmatch(package)
  815.         result = ""
  816.         version = self.getVersion(installed_package,search.VERSION_RELEASE)
  817.         if len(version) > 0:
  818.             result = darkgreen("Latest version installed:")+" "+version
  819.         else:
  820.             result = darkgreen("Latest version installed:")+" [ Not Installed ]"
  821.         return result
  822.  
  823.     def getVersion(self,full_package,detail):
  824.         if len(full_package) > 1:
  825.             package_parts = portage.catpkgsplit(full_package)
  826.             if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
  827.                 result = package_parts[2]+ "-" + package_parts[3]
  828.             else:
  829.                 result = package_parts[2]
  830.         else:
  831.             result = ""
  832.         return result
  833.  
  834.  
  835. #build our package digraph
  836. def getlist(mode):
  837.     if mode=="system":
  838.         mylines=portage.settings.packages
  839.     elif mode=="world":
  840.         try:
  841.             myfile = open(os.path.join(portage.root, portage.WORLD_FILE), "r")
  842.             mylines=myfile.readlines()
  843.             myfile.close()
  844.         except OSError:
  845.             print "!!! Couldn't open "+pfile+"; exiting."
  846.             sys.exit(1)
  847.         except IOError, e:
  848.             #Permission denied is a fatal error, as opposed to a missing file
  849.             if e.errno == errno.EACCES:
  850.                 raise
  851.             else:
  852.                 if "--quiet" not in myopts:
  853.                     portage.writemsg(red("\n!!! ") + "Warning %s does not exist.\n" % os.path.join(portage.root, portage.WORLD_FILE) )
  854.                 mylines=[]
  855.     mynewlines=[]
  856.     for x in mylines:
  857.         myline=string.join(string.split(x))
  858.         if not len(myline):
  859.             continue
  860.         elif myline[0]=="#":
  861.             continue
  862.         elif mode=="system":
  863.             if myline[0]!="*":
  864.                 continue
  865.             myline=myline[1:]
  866.         mynewlines.append(myline.strip())
  867.  
  868.     # Remove everything that is package.provided from our list
  869.     for atom in mynewlines[:]:
  870.         for expanded_atom in portage.flatten(portage.dep_virtual([atom], portage.settings)):
  871.             mykey = portage.dep_getkey(expanded_atom)
  872.             if portage.settings.pprovideddict.has_key(mykey) and \
  873.                 portage.match_from_list(expanded_atom, portage.settings.pprovideddict[mykey]):
  874.                     mynewlines.remove(atom)
  875.                     break
  876.  
  877.     return mynewlines
  878.  
  879. def genericdict(mylist):
  880.     mynewdict={}
  881.     for x in mylist:
  882.         mynewdict[portage.dep_getkey(x)]=x
  883.     return mynewdict
  884.  
  885. olddbapi=None
  886. class depgraph:
  887.  
  888.     def __init__(self,myaction,myopts):
  889.         global olddbapi
  890.         self.pkgsettings = portage.config(clone=portage.settings)
  891.         if not self.pkgsettings["ARCH"]:
  892.             portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"),
  893.                 noiselevel=-1)
  894.             portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"),
  895.                 noiselevel=-1)
  896.             sys.exit(9)
  897.         self.applied_useflags = {}
  898.  
  899.         self.missingbins=[]
  900.         self.myaction=myaction
  901.         self.digraph=portage.digraph()
  902.         self.orderedkeys=[]
  903.         self.outdatedpackages=[]
  904.         self.mydbapi={}
  905.         self.mydbapi["/"] = portage.fakedbapi()
  906.         if "empty" not in myparams or portage.root != "/":
  907.             for pkg in portage.db["/"]["vartree"].getallcpv():
  908.                 self.mydbapi["/"].cpv_inject(pkg)
  909.         if portage.root != "/":
  910.             self.mydbapi[portage.root] = portage.fakedbapi()
  911.             if "empty" not in myparams:
  912.                 for pkg in portage.db[portage.root]["vartree"].getallcpv():
  913.                     self.mydbapi[portage.root].cpv_inject(pkg)
  914.  
  915.         if "--usepkg" in myopts:
  916.             portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts))
  917.  
  918.     def create(self,mybigkey,myparent=None,addme=1,myuse=None):
  919.         """creates the actual digraph of packages to merge.  return 1 on success, 0 on failure
  920.         mybigkey = specification of package to merge; myparent = parent package (one depending on me);
  921.         addme = should I be added to the tree? (for the --onlydeps mode)"""
  922.         #stuff to add:
  923.         #SLOT-aware emerge
  924.         #IUSE-aware emerge
  925.         #"no downgrade" emerge
  926.         #print "mybigkey:",mybigkey
  927.  
  928.         jbigkey=string.join(mybigkey)
  929.         if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"):
  930.             #this conditional is needed to prevent infinite recursion on already-processed deps
  931.             return 1
  932.  
  933.         update_spinner()
  934.  
  935.         mytype,myroot,mykey=mybigkey
  936.         # select the correct /var database that we'll be checking against
  937.         vardbapi=portage.db[myroot]["vartree"].dbapi
  938.  
  939.         # if the package is already on the system, we add a "nomerge"
  940.         # directive, otherwise we add a "merge" directive.
  941.         if mytype=="blocks":
  942.             # we've encountered a "blocks" node.  We will totally ignore this
  943.             # node and not add it to our digraph if it doesn't apply to us.
  944.             if addme and "--buildpkgonly" not in myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)):
  945.                 mybigkey.append(myparent.split()[2])
  946.                 self.digraph.addnode(string.join(mybigkey),myparent)
  947.             return 1
  948.  
  949.         if myuse is None:
  950.             self.pkgsettings.setcpv(mykey)
  951.             myuse = self.pkgsettings["USE"].split()
  952.         self.applied_useflags[mykey] = myuse
  953.  
  954.         merging=1
  955.         if addme:
  956.         # this is where we add the node to the list of packages to merge
  957.             if not myparent:
  958.                 # command-line specified or part of a world list...
  959.                 if ("self" not in myparams) or (("selective" in myparams) and vardbapi.cpv_exists(mykey)):
  960.                     # the package is on the system, so don't merge it.
  961.                     merging=0
  962.             elif ("selective" in myparams) and vardbapi.cpv_exists(mykey):
  963.                 merging=0
  964.  
  965.             if (merging==0 and "--newuse" in myopts and vardbapi.cpv_exists(mykey)):
  966.                 old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
  967.                 if mytype == "binary":
  968.                     iuses = portage.db["/"]["bintree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
  969.                 else:
  970.                     iuses = portage.db["/"]["porttree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
  971.                 for x in iuses:
  972.                     if (old_use.count(x) and not myuse.count(x)) or (not old_use.count(x) and myuse.count(x)):
  973.                         merging=1
  974.                         break
  975.         else:
  976.             #onlydeps mode; don't merge
  977.             merging=2
  978.         if merging==1:
  979.             mybigkey.append("merge")
  980.         else:
  981.             mybigkey.append("nomerge")
  982.  
  983.         # whatever the case, we need to add the node to our digraph so
  984.         # that children can depend upon it.
  985.         self.digraph.addnode(string.join(mybigkey),myparent)
  986.         if ("deep" not in myparams) and (not merging):
  987.             return 1
  988.         elif "recurse" not in myparams:
  989.             return 1
  990.  
  991.         edepend={}
  992.         if mytype=="binary":
  993.             mypkgparts=portage.catpkgsplit(mykey)
  994.             tbz2name = string.split(mykey, "/")[1]+".tbz2"
  995.             if tbz2name in portage.db[portage.root]["bintree"].invalids:
  996.                 sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n")
  997.                 sys.exit(1)
  998.             if portage.db[portage.root]["bintree"].isremote(mykey):
  999.                 edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name]
  1000.                 edepend["DEPEND"] =""
  1001.                 edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ")
  1002.                 edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ")
  1003.                 edepend["SLOT"]   =string.strip(edepend["SLOT"])
  1004.                 #portage.db[portage.root]["bintree"].gettbz2(mykey)
  1005.             else: # It's local.
  1006.                 mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey))
  1007.                 edepend["DEPEND"] =""
  1008.                 edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ")
  1009.                 edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ")
  1010.                 edepend["SLOT"]   =mytbz2.getfile("SLOT",mypkgparts[2])
  1011.         elif mytype=="ebuild":
  1012.             try:
  1013.                 mymeta = ["DEPEND","RDEPEND","PDEPEND"]
  1014.                 myfoo = portage.portdb.aux_get(mykey, mymeta)
  1015.                 for index in range(0,len(mymeta)):
  1016.                     edepend[mymeta[index]] = myfoo[index]
  1017.                 if "--buildpkgonly" in myopts:
  1018.                     edepend["RDEPEND"] = ""
  1019.                     edepend["PDEPEND"] = ""
  1020.             except (KeyError,IOError):
  1021.                 print "emerge: create(): aux_get() error on",mykey+"; aborting..."
  1022.                 sys.exit(1)
  1023.         mydep={}
  1024.         mp=string.join(mybigkey)
  1025.  
  1026.         try:
  1027.             if myroot=="/":
  1028.                 mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
  1029.                 if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
  1030.                     return 0
  1031.             else:
  1032.                 mydep["/"]=edepend["DEPEND"]
  1033.                 mydep[myroot]=edepend["RDEPEND"]
  1034.                 if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
  1035.                     return 0
  1036.                 if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
  1037.                     return 0
  1038.     
  1039.             if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
  1040.                 # Post Depend -- Add to the list without a parent, as it depends
  1041.                 # on a package being present AND must be built after that package.
  1042.                 if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
  1043.                     return 0
  1044.         except ValueError, e:
  1045.             pkgs = e.args[0]
  1046.             portage.writemsg("\n\n!!! An atom in the dependencies " + \
  1047.                 "is not fully-qualified. Multiple matches:\n\n", noiselevel=-1)
  1048.             for cpv in pkgs:
  1049.                 portage.writemsg("    %s\n" % cpv, noiselevel=-1)
  1050.             portage.writemsg("\n", noiselevel=-1)
  1051.             if mytype == "binary":
  1052.                 portage.writemsg(
  1053.                     "!!! This binary package cannot be installed: '%s'\n" % \
  1054.                     mykey, noiselevel=-1)
  1055.             elif mytype == "ebuild":
  1056.                 myebuild, mylocation = portage.portdb.findname2(mykey)
  1057.                 portage.writemsg("!!! This ebuild cannot be installed: " + \
  1058.                     "'%s'\n" % myebuild, noiselevel=-1)
  1059.             portage.writemsg("!!! Please notify the package maintainer " + \
  1060.                 "that atoms must be fully-qualified.\n", noiselevel=-1)
  1061.             return 0
  1062.  
  1063.         return 1
  1064.  
  1065.     def select_files(self,myfiles):
  1066.         "given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
  1067.         myfavorites=[]
  1068.         for x in myfiles:
  1069.             ext = os.path.splitext(x)[1]
  1070.             if ext==".tbz2":
  1071.                 if not os.path.exists(x):
  1072.                     if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x):
  1073.                         x=self.pkgsettings["PKGDIR"]+"/All/"+x
  1074.                     elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x):
  1075.                         x=self.pkgsettings["PKGDIR"]+"/"+x
  1076.                     else:
  1077.                         print "\n\n!!! Binary package '"+str(x)+"' does not exist."
  1078.                         print "!!! Please ensure the tbz2 exists as specified.\n"
  1079.                         sys.exit(1)
  1080.                 mytbz2=xpak.tbz2(x)
  1081.                 mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
  1082.                 if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x):
  1083.                     print red("\n*** You need to adjust PKGDIR to emerge this package.\n")
  1084.                     sys.exit(1)
  1085.                 if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in myopts):
  1086.                     return (0,myfavorites)
  1087.                 elif not "--oneshot" in myopts:
  1088.                     myfavorites.append(mykey)
  1089.             elif ext==".ebuild":
  1090.                 x = os.path.realpath(x)
  1091.                 mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.splitext(os.path.basename(x))[0]
  1092.                 ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey)
  1093.                 if ebuild_path:
  1094.                     if os.path.realpath(ebuild_path) != x:
  1095.                         print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
  1096.                         sys.exit(1)
  1097.                     if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)):
  1098.                         print red("\n*** You are emerging a masked package. It is MUCH better to use")
  1099.                         print red("*** /etc/portage/package.* to accomplish this. See portage(5) man")
  1100.                         print red("*** page for details.")
  1101.                         countdown(EMERGE_WARNING_DELAY, "Continuing...")
  1102.                 else:
  1103.                     raise portage_exception.PackageNotFound(
  1104.                         "%s is not in a valid portage tree hierarchy or does not exist" % x)
  1105.                 if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in myopts):
  1106.                     return (0,myfavorites)
  1107.                 elif not "--oneshot" in myopts:
  1108.                     myfavorites.append(mykey)
  1109.             else:
  1110.                 if not is_valid_package_atom(x):
  1111.                     portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x,
  1112.                         noiselevel=-1)
  1113.                     portage.writemsg("!!! Please check ebuild(5) for full details.\n")
  1114.                     portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
  1115.                     return (0,[])
  1116.                 try:
  1117.                     mykey=portage.dep_expand(x,mydb=portage.portdb)
  1118.                 except ValueError, errpkgs:
  1119.                     print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous.  Please specify"
  1120.                     print "!!! one of the following fully-qualified ebuild names instead:\n"
  1121.                     for i in errpkgs[0]:
  1122.                         print "    " + green(i)
  1123.                     print
  1124.                     sys.exit(1)
  1125.  
  1126.                 # select needs to return 0 on dep_check failure
  1127.  
  1128.                 sys.stdout.flush()
  1129.                 sys.stderr.flush()
  1130.  
  1131.                 try:
  1132.                     self.mysd = self.select_dep(portage.root,mykey,arg=x)
  1133.                 except portage_exception.MissingSignature, e:
  1134.                     portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
  1135.                     portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
  1136.                     portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
  1137.                     portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
  1138.                     portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
  1139.                     sys.exit(1)
  1140.                 except portage_exception.InvalidSignature, e:
  1141.                     portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
  1142.                     portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
  1143.                     portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
  1144.                     portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
  1145.                     portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
  1146.                     sys.exit(1)
  1147.                 except SystemExit, e:
  1148.                     raise # Needed else can't exit
  1149.                 except Exception, e:
  1150.                     if "--debug" in myopts:
  1151.                         raise
  1152.                     print "\n\n!!! Problem in",mykey,"dependencies."
  1153.                     print "!!!",str(e),e.__module__
  1154.                     sys.exit(1)
  1155.  
  1156.                 if not self.mysd:
  1157.                     return (0,myfavorites)
  1158.                 elif not "--oneshot" in myopts:
  1159.                     myfavorites.append(portage.dep_getkey(mykey))
  1160.  
  1161.         missing=0
  1162.         if "--usepkgonly" in myopts:
  1163.             for x in self.digraph.dict.keys():
  1164.                 xs=string.split(x," ")
  1165.                 if (xs[0] != "binary") and (xs[3]=="merge"):
  1166.                     if missing == 0:
  1167.                         print
  1168.                     missing += 1
  1169.                     print "Missing binary for:",xs[2]
  1170.  
  1171.         # We're true here unless we are missing binaries.
  1172.         return (not missing,myfavorites)
  1173.  
  1174.     def is_newer_ver_installed(self,myroot,pkg,pkgver):
  1175.         "if there is a version of pkg installed newer than pkgver, return it"
  1176.         vardbapi=portage.db[myroot]["vartree"].dbapi
  1177.  
  1178.         matches=portage.db[myroot]["vartree"].dbapi.match(pkg)
  1179.         if matches:
  1180.             myslot=portage.db["/"]["porttree"].getslot(pkgver)
  1181.             for match in matches:
  1182.                 if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0:
  1183.                     curslot=portage.db[myroot]["vartree"].getslot(match)
  1184.                     if curslot == myslot:
  1185.                         return match
  1186.  
  1187.     def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False):
  1188.         "given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure"
  1189.         if "--debug" in myopts:
  1190.             print
  1191.             print "Parent:   ",myparent
  1192.             print "Depstring:",depstring
  1193.         if not arg:
  1194.             #processing dependencies
  1195.             mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkgonly" in myopts),myroot=myroot)
  1196.  
  1197.             if not mycheck[0]:
  1198.                 mymerge=[]
  1199.             else:
  1200.                 mymerge=mycheck[1]
  1201.  
  1202.         else:
  1203.             #we're processing a command-line argument; unconditionally merge it even if it's already merged
  1204.             mymerge=[depstring]
  1205.  
  1206.         # dep_check has been run so we can now add our parent to our
  1207.         # build state to update virtuals and other settings. This
  1208.         # happens after the package is added to the tree so that a
  1209.         # package can depend on a virtual which it satisfies.
  1210.         if myparent:
  1211.             myp = myparent.split()
  1212.             if myp[3]=="merge":
  1213.                 self.mydbapi[myroot].cpv_inject(myp[2])
  1214.                 if myp[0]=="binary":
  1215.                     self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi)
  1216.                 else:
  1217.                     self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi)
  1218.  
  1219.         if not mymerge:
  1220.             return 1
  1221.  
  1222.         if "--debug" in myopts:
  1223.             print "Candidates:",mymerge
  1224.         for x in mymerge:
  1225.             myk=None
  1226.             binpkguseflags=None
  1227.             if x[0]=="!":
  1228.                 # if this package is myself, don't append it to block list.
  1229.                 if "--debug" in myopts:
  1230.                     print "Myparent",myparent
  1231.                 if (myparent):
  1232.                     if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]):
  1233.                         # myself, so exit.
  1234.                         continue
  1235.                 # adding block
  1236.                 myk=["blocks",myroot,x[1:]]
  1237.             else:
  1238.                 #We are not processing a blocker but a normal dependency
  1239.                 myeb=None
  1240.                 myeb_matches = portage.portdb.xmatch("match-visible",x)
  1241.                 if ("--usepkgonly" not in myopts):
  1242.                     myeb=portage.best(myeb_matches)
  1243.  
  1244.                 myeb_pkg=None
  1245.                 if ("--usepkg" in myopts):
  1246.                     # The next line assumes the binarytree has been populated.
  1247.                     # XXX: Need to work out how we use the binary tree with roots.
  1248.                     myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x)
  1249.                     if ("--usepkgonly" not in myopts):
  1250.                         # Remove any binary package entries that are masked in the portage tree (#55871)
  1251.                         for idx in range(len(myeb_pkg_matches)-1,-1,-1):
  1252.                             if myeb_pkg_matches[idx] not in myeb_matches:
  1253.                                 del myeb_pkg_matches[idx]
  1254.                     myeb_pkg = portage.best(myeb_pkg_matches)
  1255.  
  1256.                 if not myeb_pkg:
  1257.                     myeb_pkg = None
  1258.                 elif ("--newuse" in myopts):
  1259.                     iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0])
  1260.                     old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0])
  1261.                     self.pkgsettings.setcpv(myeb_pkg)
  1262.                     now_use=string.split(self.pkgsettings["USE"])
  1263.                     for x in iuses:
  1264.                         if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
  1265.                             myeb_pkg = None
  1266.                             break
  1267.  
  1268.                 if (not myeb) and (not myeb_pkg):
  1269.                     if raise_on_missing:
  1270.                         raise ValueError
  1271.                     if not arg:
  1272.                         xinfo='"'+x+'"'
  1273.                     else:
  1274.                         xinfo='"'+arg+'"'
  1275.                     if myparent:
  1276.                         xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')'
  1277.                     alleb=portage.portdb.xmatch("match-all",x)
  1278.                     if alleb:
  1279.                         if "--usepkgonly" not in myopts:
  1280.                             print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
  1281.                             print "!!! One of the following masked packages is required to complete your request:"
  1282.                             oldcomment = ""
  1283.                             for p in alleb:
  1284.                                 mreasons = portage.getmaskingstatus(p)
  1285.                                 print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")"
  1286.                                 comment = portage.getmaskingreason(p)
  1287.                                 if comment and comment != oldcomment:
  1288.                                     print comment
  1289.                                     oldcomment = comment
  1290.                             print
  1291.                             print "For more information, see MASKED PACKAGES section in the emerge man page or "
  1292.                             print "refer to the Gentoo Handbook."
  1293.                         else:
  1294.                             print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
  1295.                             print "!!! Either add a suitable binary package or compile from an ebuild."
  1296.                     else:
  1297.                         print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
  1298.                     if myparent:
  1299.                         print xfrom
  1300.                     print
  1301.                     return 0
  1302.  
  1303.                 if "--debug" in myopts:
  1304.                     print "ebuild:",myeb
  1305.                     print "binpkg:",myeb_pkg
  1306.  
  1307.                 if myeb and myeb_pkg:
  1308.                     myeb_s     = portage.catpkgsplit(myeb)
  1309.                     myeb_s     = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]]
  1310.                     myeb_pkg_s = portage.catpkgsplit(myeb_pkg)
  1311.                     myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]]
  1312.  
  1313.                     if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild
  1314.                         myeb = None
  1315.                     else:
  1316.                         myeb_pkg = None
  1317.  
  1318.                 if myeb:
  1319.                     myk=["ebuild",myroot,myeb]
  1320.                 elif myeb_pkg:
  1321.                     binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg)
  1322.                     myk=["binary",myroot,myeb_pkg]
  1323.                 else:
  1324.                     sys.stderr.write("!!! Confused... Don't know what's being used for dependency info. :(\n")
  1325.                     sys.exit(1)
  1326.  
  1327.                 #if "--usepkg" in myopts:
  1328.                 #    #If we want to use packages, see if we have a pre-built one...
  1329.                 #    mypk=portage.db["/"]["bintree"].dbapi.match(x)
  1330.                 #    if myeb in mypk:
  1331.                 #        #Use it only if it's exactly the version we want.
  1332.                 #        myk=["binary",myroot,myeb]
  1333.                 #    else:
  1334.                 #        myk=["ebuild",myroot,myeb]
  1335.                 #else:
  1336.                 #    myk=["ebuild",myroot,myeb]
  1337.             if myparent:
  1338.                 #we are a dependency, so we want to be unconditionally added
  1339.                 if not self.create(myk,myparent,myuse=binpkguseflags):
  1340.                     return 0
  1341.             else:
  1342.                 #if mysource is not set, then we are a command-line dependency and should not be added
  1343.                 #if --onlydeps is specified.
  1344.                 if not self.create(myk,myparent,"--onlydeps" not in myopts,myuse=binpkguseflags):
  1345.                     return 0
  1346.  
  1347.         if "--debug" in myopts:
  1348.             print "Exiting...",myparent
  1349.         return 1
  1350.  
  1351.  
  1352.     def altlist(self):
  1353.         mygraph=self.digraph.copy()
  1354.         dolist=["/"]
  1355.         retlist=[]
  1356.         for x in portage.db.keys():
  1357.             portage.db[x]["merge"]=[]
  1358.             if x not in dolist:
  1359.                 dolist.append(x)
  1360.         while (not mygraph.empty()):
  1361.             mycurkey=mygraph.firstzero()
  1362.             if not mycurkey:
  1363.                 print "!!! Error: circular dependencies:"
  1364.                 print
  1365.                 for x in mygraph.dict.keys():
  1366.                     for y in mygraph.dict[x][1]:
  1367.                         print y,"depends on",x
  1368.                 print
  1369.                 sys.exit(1)
  1370.             splitski=string.split(mycurkey)
  1371.             #I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
  1372.             #These lines remove already-merged things from our alt-list
  1373.             #if "--update" in myopts:
  1374.             #    if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
  1375.             #        portage.db["/"]["merge"].append(splitski)
  1376.             #else:
  1377.             portage.db[splitski[1]]["merge"].append(splitski)
  1378.             mygraph.delnode(mycurkey)
  1379.         for x in dolist:
  1380.             for y in portage.db[x]["merge"]:
  1381.                 retlist.append(y)
  1382.         return retlist
  1383.  
  1384.     def xcreate(self,mode="system"):
  1385.         global syslist
  1386.         world_problems = False
  1387.         if mode=="system":
  1388.             mylist=syslist
  1389.         else:
  1390.             #world mode
  1391.             worldlist=getlist("world")
  1392.             sysdict=genericdict(syslist)
  1393.             worlddict=genericdict(worldlist)
  1394.  
  1395.             for x in worlddict.keys():
  1396.                 if not portage.isvalidatom(x):
  1397.                     world_problems = True
  1398.                 elif not portage.db["/"]["vartree"].dbapi.match(x):
  1399.                     world_problems = True
  1400.                 else:
  1401.                     sysdict[x]=worlddict[x]
  1402.  
  1403.             mylist = sysdict.keys()
  1404.  
  1405.         newlist = []
  1406.         for atom in mylist:
  1407.             if portage.dep_getkey(atom).split("/")[-1] == "portage":
  1408.                 newlist.insert(0, atom)
  1409.             else:
  1410.                 newlist.append(atom)
  1411.         mylist = newlist
  1412.         
  1413.         missing_atoms = []
  1414.         for mydep in mylist:
  1415.             try:
  1416.                 if not self.select_dep(portage.root, mydep, raise_on_missing=True):
  1417.                     print "\n\n!!! Problem resolving dependencies for", mydep
  1418.                     return 0
  1419.             except ValueError:
  1420.                 missing_atoms.append(mydep)
  1421.  
  1422.         if world_problems:
  1423.             print "\n!!! Problems have been detected with your world file"
  1424.             print "!!! Please run "+green("emaint --check world")+"\n"
  1425.  
  1426.         if missing_atoms and "--verbose" in myopts:
  1427.             print "\n!!! Packages for the following atoms are either all"
  1428.             print "!!! masked or don't exist:"
  1429.             print " ".join(missing_atoms) + "\n"
  1430.  
  1431.         return 1
  1432.  
  1433.     def match(self,mydep,myroot=portage.root,mykey=None):
  1434.         # support mutual exclusive deps
  1435.         mydep2=mydep
  1436.         if mydep2[0]=="!":
  1437.             mydep2=mydep[1:]
  1438.  
  1439.         if mydep[0]=="!":
  1440.             #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example)
  1441.             myk="blocks "+myroot+" "+mydep2
  1442.         else:
  1443.             myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2)
  1444.             if not myeb:
  1445.                 if not mykey:
  1446.                     print "\n!!! Error: couldn't find match for",mydep
  1447.                 else:
  1448.                     print "\n!!! Error: couldn't find match for",mydep,"in",mykey
  1449.                 print
  1450.                 sys.exit(1)
  1451.  
  1452.             if "--usepkg" in myopts:
  1453.                 mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
  1454.                 if myeb==mypk:
  1455.                     myk="binary "+portage.root+" "+mypk
  1456.                 else:
  1457.                     myk="ebuild "+myroot+" "+myeb
  1458.             else:
  1459.                 myk="ebuild "+myroot+" "+myeb
  1460.  
  1461.         return myk
  1462.  
  1463.     def display(self,mylist,verbosity=("--quiet" in myopts and 1 or "--verbose" in myopts and 3 or 2 )):
  1464.         changelogs=[]
  1465.         p=[]
  1466.         totalsize=0
  1467.  
  1468.         if verbosity == 1:
  1469.             def create_use_string(*args):
  1470.                 return ""
  1471.         else:
  1472.             def create_use_string(name, cur_iuse, cur_use, old_iuse, old_use, is_new,
  1473.                     all_flags=(verbosity == 3), alphabetical=("--alphabetical" in myopts)):
  1474.                 enabled = []
  1475.                 if alphabetical:
  1476.                     disabled = enabled
  1477.                 else:
  1478.                     disabled = []
  1479.                 for flag in cur_iuse:
  1480.                     if flag in cur_use:
  1481.                         if is_new or flag in old_use and all_flags:
  1482.                             enabled.append(red(flag))
  1483.                         elif flag not in old_iuse:
  1484.                             enabled.append(yellow(flag)+"%")
  1485.                         elif flag not in old_use:
  1486.                             enabled.append(green(flag)+"*")
  1487.                     else:
  1488.                         if is_new or flag in old_iuse and flag not in old_use and all_flags:
  1489.                             disabled.append(blue("-"+flag))
  1490.                         elif flag not in old_iuse:
  1491.                             disabled.append(yellow("-"+flag)+"%")
  1492.                         elif flag in old_use:
  1493.                             disabled.append(green("-"+flag)+"*")
  1494.  
  1495.                 enabled = " ".join(enabled)
  1496.                 if alphabetical:
  1497.                     disabled = ""
  1498.                 else:
  1499.                     disabled = " ".join(disabled)
  1500.                 if enabled and disabled:
  1501.                     ret = enabled + " " + disabled
  1502.                 elif enabled:
  1503.                     ret = enabled
  1504.                 else:
  1505.                     ret = disabled
  1506.                 if ret:
  1507.                     ret = '%s="%s" ' % (name, ret)
  1508.                 return ret
  1509.  
  1510.         if verbosity == 3:
  1511.             overlays = self.pkgsettings["PORTDIR_OVERLAY"].split()
  1512.             overlays_real = [os.path.realpath(t) \
  1513.                 for t in self.pkgsettings["PORTDIR_OVERLAY"].split()]
  1514.  
  1515.         if "--tree" in myopts:
  1516.             mylist.reverse()
  1517.             mygraph=self.digraph.copy()
  1518.  
  1519.         i = 0
  1520.         while i < len(mylist):
  1521.             if mylist[i][-1]=="nomerge":
  1522.                 if not ("--tree" in myopts):
  1523.                     # we don't care about this elements
  1524.                     mylist.pop(i)
  1525.                     continue
  1526.                 if (i == (len(mylist) - 1)) \
  1527.                    or (mygraph.depth(string.join(mylist[i])) \
  1528.                        >= mygraph.depth(string.join(mylist[i+1]))):
  1529.                     # end of a useless branch (may be the last one)
  1530.                     # -> delete the element and test the previous one
  1531.                     mylist.pop(i)
  1532.                     if i > 0:
  1533.                         i -= 1
  1534.                     continue
  1535.             # the branch continues, or we've found a good element.
  1536.             # -> let's see what's next, if anything
  1537.             i += 1
  1538.  
  1539.         display_overlays=False
  1540.         # files to fetch list - avoids counting a same file twice
  1541.         # in size display (verbose mode)
  1542.         myfetchlist=[]
  1543.         for x in mylist:
  1544.             pkg_type = x[0]
  1545.             pkg_key = x[2]
  1546.             if pkg_key not in self.applied_useflags:
  1547.                 if "binary" == pkg_type:
  1548.                     self.applied_useflags[pkg_key] = portage.db["/"]["bintree"].dbapi.aux_get(pkg_key, ["USE"])[0].split()
  1549.                 elif "ebuild" == pkg_type:
  1550.                     self.pkgsettings.setcpv(pkg_key)
  1551.                     self.applied_useflags[pkg_key] = self.pkgsettings["USE"].split()
  1552.  
  1553.             fetch=" "
  1554.  
  1555.             if x[0]=="blocks":
  1556.                 addl=""+red("B")+"  "+fetch+"  "
  1557.                 resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
  1558.                 print "["+x[0]+" "+addl+"]",red(resolved),
  1559.                 if resolved!=x[2]:
  1560.                     if x[3]:
  1561.                         print red("(\""+x[2]+"\" is blocking "+x[3]+")")
  1562.                     else:
  1563.                         print red("(\""+x[2]+"\")")
  1564.                 else:
  1565.                     if x[3]:
  1566.                         print red("(is blocking "+x[3]+")")
  1567.                     else:
  1568.                         print
  1569.             else:
  1570.                 if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
  1571.                     fetch = red("F")
  1572.                     if portage.portdb.fetch_check(x[2], self.applied_useflags[x[2]]):
  1573.                         fetch = green("f")
  1574.  
  1575.                 #we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
  1576.                 #param is used for -u, where you still *do* want to see when something is being upgraded.
  1577.                 myoldbest=""
  1578.                 if (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]):
  1579.                     addl="  "+yellow("R")+fetch+"  "
  1580.                 elif (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]):
  1581.                     if x[0] == "binary":
  1582.                         mynewslot=portage.db["/"]["bintree"].getslot(x[2])
  1583.                     elif x[0] == "ebuild":
  1584.                         mynewslot=portage.db["/"]["porttree"].getslot(x[2])
  1585.                     myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])
  1586.                     myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist)
  1587.                     if myinslotlist:
  1588.                         myoldbest=portage.best(myinslotlist)
  1589.                         addl="   "+fetch
  1590.                         if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
  1591.                             # Downgrade in slot
  1592.                             addl+=turquoise("U")+blue("D")
  1593.                         else:
  1594.                             # Update in slot
  1595.                             addl+=turquoise("U")+" "
  1596.                     else:
  1597.                         # New slot, mark it new.
  1598.                         addl=" "+green("NS")+fetch+"  "
  1599.  
  1600.                     if "--changelog" in myopts:
  1601.                         changelogs.extend(self.calc_changelog(
  1602.                             portage.portdb.findname(x[2]),
  1603.                             portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])),
  1604.                             x[2]
  1605.                             ))
  1606.                 else:
  1607.                     addl=" "+green("N")+" "+fetch+"  "
  1608.  
  1609.                 verboseadd=""
  1610.                 
  1611.                 if x[2] in self.applied_useflags:
  1612.                     # USE flag display
  1613.                     if x[0] == "binary":
  1614.                         cur_iuse = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0])
  1615.                     elif x[0] == "ebuild":
  1616.                         cur_iuse = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0])
  1617.                     else:
  1618.                         cur_iuse = []
  1619.  
  1620.                     cur_iuse = portage.unique_array(cur_iuse)
  1621.                     cur_iuse = [flag for flag in cur_iuse if flag not in portage.settings.usemask]
  1622.                     cur_iuse.sort()
  1623.                     cur_use = self.applied_useflags[x[2]]
  1624.                     cur_use = [flag for flag in cur_use if flag in cur_iuse]
  1625.  
  1626.                     if myoldbest:
  1627.                         pkg = myoldbest
  1628.                     else:
  1629.                         pkg = x[2]
  1630.                     if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg):
  1631.                         (old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"])
  1632.                         old_iuse = portage.unique_array(old_iuse.split())
  1633.                         old_iuse.sort()
  1634.                         old_use = old_use.split()
  1635.                         is_new = False
  1636.                     else:
  1637.                         old_iuse = []
  1638.                         old_use = []
  1639.                         is_new = True
  1640.                     old_iuse = [flag for flag in old_iuse if flag not in portage.settings.usemask]
  1641.                     old_use = [flag for flag in old_use if flag in old_iuse]
  1642.  
  1643.                     use_expand = portage.settings["USE_EXPAND"].lower().split()
  1644.                     use_expand.sort()
  1645.                     use_expand.reverse()
  1646.                     use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].lower().split()
  1647.  
  1648.                     def map_to_use_expand(myvals):
  1649.                         ret = {}
  1650.                         for exp in use_expand:
  1651.                             ret[exp] = []
  1652.                             for val in myvals[:]:
  1653.                                 if val.startswith(exp.lower()+"_"):
  1654.                                     ret[exp].append(val[len(exp)+1:])
  1655.                                     myvals.remove(val)
  1656.                         ret["USE"] = myvals
  1657.                         for exp in use_expand_hidden:
  1658.                             if exp in ret:
  1659.                                 del ret[exp]
  1660.                         return ret
  1661.  
  1662.                     cur_iuse_map = map_to_use_expand(cur_iuse)
  1663.                     cur_use_map = map_to_use_expand(cur_use)
  1664.                     old_iuse_map = map_to_use_expand(old_iuse)
  1665.                     old_use_map = map_to_use_expand(old_use)
  1666.  
  1667.                     use_expand.sort()
  1668.                     use_expand.insert(0, "USE")
  1669.                     
  1670.                     for key in use_expand:
  1671.                         if key in use_expand_hidden:
  1672.                             continue
  1673.                         verboseadd += create_use_string(key.upper(), cur_iuse_map[key], cur_use_map[key],
  1674.                                                         old_iuse_map[key], old_use_map[key], is_new)
  1675.  
  1676.                 if verbosity == 3:
  1677.                     # size verbose
  1678.                     mysize=0
  1679.                     if x[0] == "ebuild" and x[-1]!="nomerge":
  1680.                         myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug)
  1681.                         if myfilesdict is None:
  1682.                             myfilesdict="[empty/missing/bad digest]"
  1683.                         else:
  1684.                             for myfetchfile in myfilesdict.keys():
  1685.                                 if myfetchfile not in myfetchlist:
  1686.                                     mysize+=myfilesdict[myfetchfile]
  1687.                                     myfetchlist.append(myfetchfile)
  1688.                             totalsize+=mysize
  1689.                         verboseadd+=format_size(mysize)+" "
  1690.  
  1691.                     # overlay verbose
  1692.                     # XXX: Invalid binaries have caused tracebacks here. 'if file_name'
  1693.                     # x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge']
  1694.                     file_name=portage.portdb.findname(x[2])
  1695.                     if file_name: # It might not exist in the tree
  1696.                         dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..")
  1697.                         if (overlays_real.count(dir_name)>0):
  1698.                             verboseadd+=teal("["+str(overlays_real.index(
  1699.                                 os.path.normpath(dir_name))+1)+"]")+" "
  1700.                             display_overlays=True
  1701.                     else:
  1702.                         verboseadd += "[No ebuild?]"
  1703.  
  1704.                 xs=portage.pkgsplit(x[2])
  1705.                 if xs[2]=="r0":
  1706.                     xs[2]=""
  1707.                 else:
  1708.                     xs[2]="-"+xs[2]
  1709.  
  1710.                 if self.pkgsettings.has_key("COLUMNWIDTH"):
  1711.                     mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"])
  1712.                 else:
  1713.                     mywidth=130
  1714.                 oldlp=mywidth-30
  1715.                 newlp=oldlp-30
  1716.  
  1717.                 indent=""
  1718.                 if ("--tree" in myopts):
  1719.                     indent=" "*mygraph.depth(string.join(x))
  1720.  
  1721.                 if myoldbest:
  1722.                     myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
  1723.                     if myoldbest[-3:]=="-r0":
  1724.                         myoldbest=myoldbest[:-3]
  1725.                     myoldbest=blue("["+myoldbest+"]")
  1726.  
  1727.                 if x[1]!="/":
  1728.                     if myoldbest:
  1729.                         myoldbest +=" "
  1730.                     if "--columns" in myopts:
  1731.                         if "--quiet" in myopts:
  1732.                             myprint=addl+" "+indent+darkgreen(xs[0])
  1733.                             myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
  1734.                             myprint=myprint+myoldbest
  1735.                             myprint=myprint+darkgreen("to "+x[1])
  1736.                         else:
  1737.                             myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
  1738.                             if (newlp-nc_len(myprint)) > 0:
  1739.                                 myprint=myprint+(" "*(newlp-nc_len(myprint)))
  1740.                             myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
  1741.                             if (oldlp-nc_len(myprint)) > 0:
  1742.                                 myprint=myprint+" "*(oldlp-nc_len(myprint))
  1743.                             myprint=myprint+myoldbest
  1744.                             myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
  1745.                     else:
  1746.                         myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+darkgreen("to "+x[1])+" "+verboseadd
  1747.                 else:
  1748.                     if "--columns" in myopts:
  1749.                         if "--quiet" in myopts:
  1750.                             myprint=addl+" "+indent+darkgreen(xs[0])
  1751.                             myprint=myprint+" "+green(xs[1]+xs[2])+" "
  1752.                             myprint=myprint+myoldbest
  1753.                         else:
  1754.                             myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
  1755.                             if (newlp-nc_len(myprint)) > 0:
  1756.                                 myprint=myprint+(" "*(newlp-nc_len(myprint)))
  1757.                             myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
  1758.                             if (oldlp-nc_len(myprint)) > 0:
  1759.                                 myprint=myprint+(" "*(oldlp-nc_len(myprint)))
  1760.                             myprint=myprint+myoldbest+"  "+verboseadd
  1761.                     else:
  1762.                         if x[3]=="nomerge":
  1763.                             myprint=darkblue("[nomerge      ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd
  1764.                         else:
  1765.                             myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd
  1766.                 p.append(myprint)
  1767.  
  1768.             mysplit = portage.pkgsplit(x[2])
  1769.             if "--tree" not in myopts and mysplit and len(mysplit) == 3 and \
  1770.                 mysplit[0] == "sys-apps/portage" and x[1] == "/":
  1771.  
  1772.                 if mysplit[2] == "r0":
  1773.                     myversion = mysplit[1]
  1774.                 else:
  1775.                     myversion = "%s-%s" % (mysplit[1], mysplit[2])
  1776.  
  1777.                 if myversion != portage.VERSION :
  1778.                     if "--emptytree" in myopts:
  1779.                         p.append(red("***")+" Please update portage to the above version before proceeding.")
  1780.                         p.append("    Failure to do so may result in failed or improper merges.")
  1781.                         p.append("    A simple '"+green("emerge portage")+"' is sufficient.")
  1782.                         p.append("")
  1783.                     elif mylist.index(x) < len(mylist) - 1 and \
  1784.                         "livecvsportage" not in portage.settings.features:
  1785.                         p.append(red("*** Portage will stop merging at this point and reload itself,"))
  1786.                         p.append(red("    then resume the merge."))
  1787.                         print
  1788.             del mysplit
  1789.  
  1790.         for x in p:
  1791.             print x
  1792.  
  1793.         if verbosity == 3:
  1794.             print
  1795.             print "Total size of downloads: "+format_size(totalsize)
  1796.             if overlays and display_overlays:
  1797.                 print "Portage overlays:"
  1798.                 y=0
  1799.                 for x in overlays:
  1800.                     y=y+1
  1801.                     print " "+teal("["+str(y)+"]"),x
  1802.  
  1803.         if "--changelog" in myopts:
  1804.             print
  1805.             for revision,text in changelogs:
  1806.                 print bold('*'+revision)
  1807.                 sys.stdout.write(text)
  1808.  
  1809.     def calc_changelog(self,ebuildpath,current,next):
  1810.         current = '-'.join(portage.catpkgsplit(current)[1:])
  1811.         if current.endswith('-r0'): current = current[:-3]
  1812.         next = '-'.join(portage.catpkgsplit(next)[1:])
  1813.         if next.endswith('-r0'): next = next[:-3]
  1814.         changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
  1815.         try:
  1816.             changelog = open(changelogpath).read()
  1817.         except SystemExit, e:
  1818.             raise # Needed else can't exit
  1819.         except:
  1820.             return []
  1821.         divisions = self.find_changelog_tags(changelog)
  1822.         #print 'XX from',current,'to',next
  1823.         #for div,text in divisions: print 'XX',div
  1824.         # skip entries for all revisions above the one we are about to emerge
  1825.         for i in range(len(divisions)):
  1826.             if divisions[i][0]==next:
  1827.                 divisions = divisions[i:]
  1828.                 break
  1829.         # find out how many entries we are going to display
  1830.         for i in range(len(divisions)):
  1831.             if divisions[i][0]==current:
  1832.                 divisions = divisions[:i]
  1833.                 break
  1834.         else:
  1835.             # couldnt find the current revision in the list. display nothing
  1836.             return []
  1837.         return divisions
  1838.  
  1839.     def find_changelog_tags(self,changelog):
  1840.         divs = []
  1841.         release = None
  1842.         while 1:
  1843.             match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M)
  1844.             if match is None:
  1845.                 if release is not None:
  1846.                     divs.append((release,changelog))
  1847.                 return divs
  1848.             if release is not None:
  1849.                 divs.append((release,changelog[:match.start()]))
  1850.             changelog = changelog[match.end():]
  1851.             release = match.group(1)
  1852.             if release.endswith('.ebuild'):
  1853.                 release = release[:-7]
  1854.             if release.endswith('-r0'):
  1855.                 release = release[:-3]
  1856.  
  1857.     def outdated(self):
  1858.         return self.outdatedpackages
  1859.  
  1860.     def merge(self,mylist):
  1861.         returnme=0
  1862.         mymergelist=[]
  1863.  
  1864.         #check for blocking dependencies
  1865.         if ("--fetchonly" not in myopts) and ("--buildpkgonly" not in myopts):
  1866.             for x in mylist:
  1867.                 if x[0]=="blocks":
  1868.                     print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
  1869.                     print   "!!!        the two packages cannot be installed on the same system together."
  1870.                     print   "!!!        Please use 'emerge --pretend' to determine blockers."
  1871.                     print
  1872.                     if ("--pretend" not in myopts):
  1873.                         try:
  1874.                             del portage.mtimedb["resume"]
  1875.                         except KeyError:
  1876.                             pass
  1877.                         sys.exit(1)
  1878.  
  1879.         #buildsyspkg: I need mysysdict also on resume (moved from the else block)
  1880.         mysysdict=genericdict(syslist)
  1881.         if ("--resume" in myopts):
  1882.             # We're resuming.
  1883.             print green("*** Resuming merge...")
  1884.             emergelog(" *** Resuming merge...")
  1885.             mymergelist=portage.mtimedb["resume"]["mergelist"][:]
  1886.             if ("--skipfirst" in myopts) and mymergelist:
  1887.                 del portage.mtimedb["resume"]["mergelist"][0]
  1888.                 del mymergelist[0]
  1889.             validate_merge_list(mymergelist)
  1890.         else:
  1891.             myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE))
  1892.             myfavdict=genericdict(myfavs)
  1893.             for x in range(len(mylist)):
  1894.                 if mylist[x][3]!="nomerge":
  1895.                     # Add to the mergelist
  1896.                     mymergelist.append(mylist[x])
  1897.                 else:
  1898.                     myfavkey=portage.cpv_getkey(mylist[x][2])
  1899.                     if "--onlydeps" in myopts:
  1900.                         continue
  1901.                     # Add to the world file. Since we won't be able to later.
  1902.                     if (not "--fetchonly" in myopts) and (myfavkey in favorites):
  1903.                         #don't record if already in system profile or already recorded
  1904.                         if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
  1905.                             #we don't have a favorites entry for this package yet; add one
  1906.                             myfavdict[myfavkey]=myfavkey
  1907.                             print ">>> Recording",myfavkey,"in \"world\" favorites file..."
  1908.             if not "--fetchonly" in myopts:
  1909.                 portage.write_atomic(
  1910.                     os.path.join(portage.root, portage.WORLD_FILE),
  1911.                     "\n".join(myfavdict.values()))
  1912.  
  1913.             portage.mtimedb["resume"]["mergelist"]=mymergelist[:]
  1914.  
  1915.         # We need to yank the harmful-to-new-builds settings from features.
  1916.         myorigfeat=self.pkgsettings["FEATURES"]
  1917.         myfeat=myorigfeat.split()
  1918.         while ("keeptemp" in myfeat):
  1919.             del myfeat[myfeat.index("keeptemp")]
  1920.         while ("keepwork" in myfeat):
  1921.             del myfeat[myfeat.index("keepwork")]
  1922.  
  1923.         self.pkgsettings["FEATURES"]=string.join(myfeat)
  1924.  
  1925.         if "parallel-fetch" in myfeat and not ("--ask" in myopts or "--pretend" in myopts or "--fetchonly" in myopts):
  1926.             if "distlocks" not in myfeat:
  1927.                 print red("!!!")
  1928.                 print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
  1929.                 print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
  1930.                 print red("!!!")
  1931.             elif len(mymergelist) > 1:
  1932.                 print ">>> starting parallel fetching"
  1933.                 pid = os.fork()
  1934.                 if not pid:
  1935.                     sys.stdin.close()
  1936.                     sys.stdout.close()
  1937.                     sys.stderr.close()
  1938.                     time.sleep(3) # allow the parent to have first fetch
  1939.                     fetchlog = "/var/log/emerge-fetch.log"
  1940.                     sys.stdout = open(fetchlog, "w")
  1941.                     sys.stderr = sys.stdout
  1942.                     os.dup2(sys.stdout.fileno(), 1)
  1943.                     os.dup2(sys.stderr.fileno(), 2)
  1944.                     portage_util.apply_secpass_permissions(fetchlog,
  1945.                         uid=portage.portage_uid, gid=portage.portage_gid,
  1946.                         mode=0660)
  1947.  
  1948.                     # wipe the mtimedb so that portage doesn't attempt to flush it.
  1949.                     # do not convert this code away from a fork without correcting this.
  1950.                     portage.mtimedb = None
  1951.                     for x in ("autoaddcvs", "cvs"):
  1952.                         try:    myfeat.remove(x)
  1953.                         except ValueError: pass
  1954.                     self.pkgsettings["FEATURES"] = " ".join(myfeat)
  1955.                     ret = 0
  1956.                     for x in mymergelist:
  1957.                         if x[0] != "ebuild":
  1958.                             continue
  1959.                         try:
  1960.                             ret = portage.doebuild(portage.portdb.findname(x[2]), "fetch", x[1], self.pkgsettings,
  1961.                                 cleanup=0, fetchonly=True, tree="porttree")
  1962.                         except SystemExit:
  1963.                             raise
  1964.                         except Exception:
  1965.                             ret = 1
  1966.                     sys.exit(0)
  1967.                 portage.portage_exec.spawned_pids.append(pid)
  1968.  
  1969.         mergecount=0
  1970.         for x in mymergelist:
  1971.             mergecount+=1
  1972.             myroot=x[1]
  1973.             pkgindex=2
  1974.             if x[0]=="blocks":
  1975.                 pkgindex=3
  1976.             y=portage.portdb.findname(x[pkgindex])
  1977.             if not "--pretend" in myopts:
  1978.                 print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
  1979.                 emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
  1980.  
  1981.             self.pkgsettings["EMERGE_FROM"] = x[0][:]
  1982.             self.pkgsettings.backup_changes("EMERGE_FROM")
  1983.             self.pkgsettings.reset()
  1984.  
  1985.             #buildsyspkg: Check if we need to _force_ binary package creation
  1986.             issyspkg = ("buildsyspkg" in myfeat) \
  1987.                     and x[0] != "blocks" \
  1988.                     and mysysdict.has_key(portage.cpv_getkey(x[2])) \
  1989.                     and not ("--buildpkg" in myopts)
  1990.             if x[0] in ["ebuild","blocks"]:
  1991.                 if (x[0]=="blocks") and ("--fetchonly" not in myopts):
  1992.                     raise Exception, "Merging a blocker"
  1993.                 elif ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
  1994.                     if ("--fetch-all-uri" in myopts):
  1995.                         retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,fetchall=1,tree="porttree")
  1996.                     else:
  1997.                         retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,tree="porttree")
  1998.                     if (retval is None) or retval:
  1999.                         print
  2000.                         print "!!! Fetch for",y,"failed, continuing..."
  2001.                         print
  2002.                         returnme=1
  2003.                     continue
  2004.                 elif "--buildpkg" in myopts or issyspkg:
  2005.                     #buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
  2006.                     if issyspkg:
  2007.                         print ">>> This is a system package, let's pack a rescue tarball."
  2008.                         #emergelog(">>> This is a system package, let's pack a rescue tarball.")
  2009.                     #create pkg, then merge pkg
  2010.                     short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
  2011.                     emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
  2012.                     retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
  2013.                     if (retval is None):
  2014.                         portage_util.writemsg("Unable to run required binary.\n",
  2015.                             noiselevel=-1)
  2016.                         sys.exit(127)
  2017.                     if retval:
  2018.                         sys.exit(retval)
  2019.                     short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
  2020.                     emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
  2021.                     retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug,tree="porttree")
  2022.                     if (retval is None):
  2023.                         portage_util.writemsg("Unable to run required binary.\n",
  2024.                             noiselevel=-1)
  2025.                         sys.exit(127)
  2026.                     if retval:
  2027.                         sys.exit(retval)
  2028.                     #dynamically update our database
  2029.                     if "--buildpkgonly" not in myopts:
  2030.                         portage.db[portage.root]["bintree"].inject(x[2])
  2031.                         mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
  2032.                         short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
  2033.                         emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
  2034.  
  2035.                         self.pkgsettings["EMERGE_FROM"] = "binary"
  2036.                         self.pkgsettings.backup_changes("EMERGE_FROM")
  2037.  
  2038.                         retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings)
  2039.                         if retval is None:
  2040.                             sys.exit(1)
  2041.                     elif "noclean" not in self.pkgsettings.features:
  2042.                         portage.doebuild(y, "clean", myroot, self.pkgsettings,
  2043.                             edebug, tree="porttree")
  2044.                 else:
  2045.                     short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
  2046.                     emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
  2047.                     retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
  2048.                     if (retval is None):
  2049.                         portage_util.writemsg("Unable to run required binary.\n",
  2050.                             noiselevel=-1)
  2051.                         sys.exit(127)
  2052.                     if retval:
  2053.                         sys.exit(retval)
  2054.                     short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
  2055.                     emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
  2056.                     retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug,tree="porttree")
  2057.                     if (retval is None):
  2058.                         portage_util.writemsg("Unable to run required binary.\n",
  2059.                             noiselevel=-1)
  2060.                         sys.exit(127)
  2061.                     if retval:
  2062.                         sys.exit(retval)
  2063.                     #dynamically update our database
  2064.             elif x[0]=="binary":
  2065.                 #merge the tbz2
  2066.                 mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
  2067.                 if portage.db[portage.root]["bintree"].isremote(x[2]):
  2068.                     short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
  2069.                     emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
  2070.                     if not portage.db[portage.root]["bintree"].gettbz2(x[2]):
  2071.                         sys.exit(1)
  2072.  
  2073.                 if ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
  2074.                     continue
  2075.  
  2076.                 short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
  2077.                 emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
  2078.                 retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings)
  2079.                 if retval is None:
  2080.                     sys.exit(1)
  2081.                 #need to check for errors
  2082.             if "--buildpkgonly" not in myopts:
  2083.                 portage.db[x[1]]["vartree"].inject(x[2])
  2084.                 myfavkey=portage.cpv_getkey(x[2])
  2085.                 if "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts and myfavkey in favorites:
  2086.                     myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE))
  2087.                     myfavdict=genericdict(myfavs)
  2088.                     mysysdict=genericdict(syslist)
  2089.                     #don't record if already in system profile or already recorded
  2090.                     if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
  2091.                         #we don't have a favorites entry for this package yet; add one
  2092.                         myfavdict[myfavkey]=myfavkey
  2093.                         print ">>> Recording",myfavkey,"in \"world\" favorites file..."
  2094.                         emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")")
  2095.                         portage.write_atomic(
  2096.                         os.path.join(myroot, portage.WORLD_FILE),
  2097.                         "\n".join(myfavdict.values()))
  2098.  
  2099.                 if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
  2100.                     # Clean the old package that we have merged over top of it.
  2101.                     if self.pkgsettings["AUTOCLEAN"]=="yes":
  2102.                         xsplit=portage.pkgsplit(x[2])
  2103.                         emergelog(" >>> AUTOCLEAN: "+xsplit[0])
  2104.                         if x[1] == portage.settings["ROOT"]:
  2105.                             # Compare against portage.settings["ROOT"] because
  2106.                             # the value of self.pkgsettings["ROOT"] does not
  2107.                             # match the original value!
  2108.                             retval = unmerge("clean", [xsplit[0]])
  2109.                         else:
  2110.                             retval = unmerge_overlapping(x[2], x[1],
  2111.                                 self.pkgsettings, portage.db[x[1]]["vartree"])
  2112.                         if not retval:
  2113.                             emergelog(" --- AUTOCLEAN: Nothing unmerged.")
  2114.                     else:
  2115.                         portage.writemsg_stdout(colorize("WARN", "WARNING:")
  2116.                             + " AUTOCLEAN is disabled.  This can cause serious"
  2117.                             + " problems due to overlapping packages.\n")
  2118.  
  2119.                     # Figure out if we need a restart.
  2120.                     mysplit=portage.pkgsplit(x[2])
  2121.                     if mysplit[0] == "sys-apps/portage" and x[1] == "/":
  2122.                         myver=mysplit[1]+"-"+mysplit[2]
  2123.                         if myver[-3:]=='-r0':
  2124.                             myver=myver[:-3]
  2125.                         if (myver != portage.VERSION) and \
  2126.                            ("livecvsportage" not in portage.settings.features):
  2127.                             if len(mymergelist) > mergecount:
  2128.                                 emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
  2129.                                 emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
  2130.                                 del portage.mtimedb["resume"]["mergelist"][0]
  2131.                                 portage.run_exitfuncs()
  2132.                                 mynewargv=[sys.argv[0],"--resume"]
  2133.                                 badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
  2134.                                 for arg in myopts:
  2135.                                     if arg in badlongopts:
  2136.                                         continue
  2137.                                     mynewargv.append(arg)
  2138.                                 # priority only needs to be adjusted on the first run
  2139.                                 os.environ["PORTAGE_NICENESS"] = "0"
  2140.                                 os.execv(mynewargv[0], mynewargv)
  2141.  
  2142.             if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
  2143.                 if "noclean" not in portage.settings.features:
  2144.                     short_msg = "emerge: (%s of %s) %s Clean Post" % \
  2145.                         (mergecount, len(mymergelist), x[pkgindex])
  2146.                     emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \
  2147.                         (mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg)
  2148.                 emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
  2149.  
  2150.             # Unsafe for parallel merges
  2151.             del portage.mtimedb["resume"]["mergelist"][0]
  2152.             # Commit after each merge so that --resume may still work in
  2153.             # in the event that portage is not allowed to exit normally
  2154.             # due to power failure, SIGKILL, etc...
  2155.             portage.commit_mtimedb()
  2156.  
  2157.         emergelog(" *** Finished. Cleaning up...")
  2158.  
  2159.         # We're out of the loop... We're done. Delete the resume data.
  2160.         if portage.mtimedb.has_key("resume"):
  2161.             del portage.mtimedb["resume"]
  2162.  
  2163.         if ("--pretend" not in myopts):
  2164.             if ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
  2165.                 if (mergecount>0):
  2166.                     if retval:
  2167.                         portage.env_update()
  2168.  
  2169.         #by doing an exit this way, --fetchonly can continue to try to
  2170.         #fetch everything even if a particular download fails.
  2171.         if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
  2172.             if returnme:
  2173.                 print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
  2174.                 sys.exit(returnme)
  2175.             else:
  2176.                 sys.exit(0)
  2177.  
  2178. def unmerge_overlapping(pkg_key, myroot, mysettings, vartree):
  2179.     """Unmerge any packages that overlap with the given package (overlapping
  2180.     packages fill the same SLOT).  Unlike emerge's unmerge() function, this
  2181.     function does not assume that packages are to be unmerged from the target
  2182.     ROOT.  This function is only needed in the case where ROOT!=/ and the
  2183.     previous version of a build time dependency (that has been upgraded) needs
  2184.     to be cleaned from / (instead of the target ROOT).  When the incorrect
  2185.     assumptions in unmerge() have been fixed, this function can be removed."""
  2186.  
  2187.     overlapping = []
  2188.     ommitted_versions = []
  2189.     mydbapi = vartree.dbapi
  2190.     myslot = mydbapi.aux_get(pkg_key, ["SLOT"])[0]
  2191.     mycp = portage.pkgsplit(pkg_key)[0]
  2192.     for other_pkg in mydbapi.cp_list(mycp):
  2193.         if other_pkg == pkg_key:
  2194.             continue
  2195.         other_slot = mydbapi.aux_get(other_pkg, ["SLOT"])[0]
  2196.         if myslot == other_slot:
  2197.             overlapping.append(other_pkg)
  2198.         else:
  2199.             ommitted_versions.append(other_pkg)
  2200.     if overlapping:
  2201.         def get_version(pkg_key):
  2202.             cp, pv, rev = portage.pkgsplit(pkg_key)
  2203.             if rev == "r0":
  2204.                 return pv
  2205.             else:
  2206.                 return "%s-%s" % (pv, rev)
  2207.         selected_versions = ",".join(map(get_version, overlapping))
  2208.         protected_version = get_version(pkg_key)
  2209.         if ommitted_versions:
  2210.             ommitted_versions = ",".join(map(get_version, ommitted_versions))
  2211.         else:
  2212.             ommitted_versions = "none"
  2213.         portage.writemsg_stdout("\n %s\n" % bold(mycp), noiselevel=-1)
  2214.         portage.writemsg_stdout("selected: ".rjust(14) + selected_versions + \
  2215.             "\n", noiselevel=-1)
  2216.         portage.writemsg_stdout("protected: ".rjust(14) + protected_version + \
  2217.             "\n", noiselevel=-1)
  2218.         portage.writemsg_stdout("omitted: ".rjust(14) + ommitted_versions + \
  2219.             "\n", noiselevel=-1)
  2220.         portage.writemsg_stdout("\n>>>" + red("'Selected'") + \
  2221.             " packages are slated for removal.\n", noiselevel=0)
  2222.         portage.writemsg_stdout(">>>" + green("'Protected'") + " and " + \
  2223.             green("'omitted'") + " packages will not be removed.\n\n",
  2224.             noiselevel=0)
  2225.         global CLEAN_DELAY
  2226.         countdown(CLEAN_DELAY, ">>> Unmerging")
  2227.         for other_pkg in overlapping:
  2228.             portage.writemsg_stdout(">>> Unmerging %s...\n" % other_pkg ,
  2229.                 noiselevel=-1)
  2230.             emergelog("=== Unmerging... (%s)" % other_pkg)
  2231.             mysplit = other_pkg.split("/")
  2232.             retval = portage.unmerge(mysplit[0], mysplit[1], myroot,
  2233.                 mysettings, mytrimworld=False, vartree=vartree)
  2234.             if retval:
  2235.                 emergelog(" !!! unmerge FAILURE: " + other_pkg)
  2236.             else:
  2237.                 emergelog(" >>> unmerge success: " + other_pkg)
  2238.         return 1
  2239.     return 0
  2240.  
  2241. def unmerge(unmerge_action, unmerge_files, raise_on_missing=True):
  2242.     candidate_catpkgs=[]
  2243.     global_unmerge=0
  2244.  
  2245.     realsyslist = getlist("system")
  2246.     syslist = []
  2247.     for x in realsyslist:
  2248.         mycp = portage.dep_getkey(x)
  2249.         if mycp in portage.settings.getvirtuals():
  2250.             providers = []
  2251.             for provider in portage.settings.getvirtuals()[mycp]:
  2252.                 if portage.db[portage.root]["vartree"].dbapi.match(provider):
  2253.                     providers.append(provider)
  2254.             if len(providers) == 1:
  2255.                 syslist.extend(providers)
  2256.         else:
  2257.             syslist.append(mycp)
  2258.  
  2259.     global myopts
  2260.     mysettings = portage.config(clone=portage.settings)
  2261.  
  2262.     if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files:
  2263.         if "unmerge"==unmerge_action:
  2264.             print
  2265.             print bold("emerge unmerge")+" can only be used with specific package names, not with "+bold("world")+" or"
  2266.             print bold("system")+" targets."
  2267.             print
  2268.             return 0
  2269.         else:
  2270.             global_unmerge=1
  2271.  
  2272.     localtree=portage.db[portage.root]["vartree"]
  2273.     # process all arguments and add all valid db entries to candidate_catpkgs
  2274.     if global_unmerge:
  2275.         if not unmerge_files or "world" in unmerge_files:
  2276.             candidate_catpkgs.extend(localtree.getallnodes())
  2277.         elif "system" in unmerge_files:
  2278.             candidate_catpkgs.extend(getlist("system"))
  2279.     else:
  2280.         #we've got command-line arguments
  2281.         if not unmerge_files:
  2282.             print "\nNo packages to unmerge have been provided.\n"
  2283.             return 0
  2284.         for x in unmerge_files:
  2285.             arg_parts=x.split('/')
  2286.             if (x[0] not in [".","/"]) and (arg_parts[-1][-7:] != ".ebuild"):
  2287.                 #possible cat/pkg or dep; treat as such
  2288.                 candidate_catpkgs.append(x)
  2289.             elif unmerge_action in ["prune","clean"]:
  2290.                 print "\n!!! Prune and clean do not accept individual ebuilds as arguments;\n    skipping.\n"
  2291.                 continue
  2292.             else:
  2293.                 # it appears that the user is specifying an installed ebuild and we're in "unmerge" mode, so it's
  2294.                 # ok.
  2295.                 if not os.path.exists(x):
  2296.                     print "\n!!! The path '"+x+"' doesn't exist.\n"
  2297.                     return 0
  2298.  
  2299.                 absx   = os.path.abspath(x)
  2300.                 sp_absx = absx.split("/")
  2301.                 if sp_absx[-1][-7:] == ".ebuild":
  2302.                     del sp_absx[-1]
  2303.                     absx = string.join(sp_absx,"/")
  2304.  
  2305.                 sp_absx_len = len(sp_absx)
  2306.  
  2307.                 vdb_path = portage.root+portage.VDB_PATH
  2308.                 vdb_len  = len(vdb_path)
  2309.  
  2310.                 sp_vdb     = vdb_path.split("/")
  2311.                 sp_vdb_len = len(sp_vdb)
  2312.  
  2313.                 if not os.path.exists(absx+"/CONTENTS"):
  2314.                     print "!!! Not a valid db dir: "+str(absx)
  2315.                     return 0
  2316.  
  2317.                 if sp_absx_len <= sp_vdb_len:
  2318.                     # The Path is shorter... so it can't be inside the vdb.
  2319.                     print spabsx
  2320.                     print absx
  2321.                     print "\n!!!",x,"cannot be inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
  2322.                     return 0
  2323.  
  2324.                 for idx in range(0,sp_vdb_len):
  2325.                     if (idx >= sp_absx_len) or (sp_vdb[idx] != sp_absx[idx]):
  2326.                         print sp_absx
  2327.                         print absx
  2328.                         print "\n!!!",x,"is not inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
  2329.                         return 0
  2330.  
  2331.                 print "="+string.join(sp_absx[sp_vdb_len:],"/")
  2332.                 candidate_catpkgs.append("="+string.join(sp_absx[sp_vdb_len:],"/"))
  2333.  
  2334.     newline=""
  2335.     if (not "--quiet" in myopts):
  2336.         newline="\n"
  2337.     if portage.settings["ROOT"] != "/":
  2338.         print darkgreen(newline+">>> Using system located in ROOT tree "+portage.settings["ROOT"])
  2339.     if (("--pretend" in myopts) or ("--ask" in myopts)) and not ("--quiet" in myopts):
  2340.         print darkgreen(newline+">>> These are the packages that would be unmerged:")
  2341.  
  2342.     pkgmap={}
  2343.     numselected=0
  2344.     for x in candidate_catpkgs:
  2345.         #cycle through all our candidate deps and determine what will and will not get unmerged
  2346.         try:
  2347.             mymatch=localtree.dep_match(x)
  2348.         except KeyError:
  2349.             mymatch=None
  2350.         except ValueError, errpkgs:
  2351.             print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous.  Please specify"
  2352.             print "!!! one of the following fully-qualified ebuild names instead:\n"
  2353.             for i in errpkgs[0]:
  2354.                 print "    " + green(i)
  2355.             print
  2356.             sys.exit(1)
  2357.  
  2358.         if not mymatch and x[0] not in "<>=~":
  2359.             #add a "=" if missing
  2360.             mymatch=localtree.dep_match("="+x)
  2361.         if not mymatch:
  2362.             if raise_on_missing:
  2363.                 raise portage_exception.PackageNotFound(x)
  2364.             else:
  2365.                 portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \
  2366.                     (x, unmerge_action), noiselevel=-1)
  2367.                 continue
  2368.         mykey=portage.key_expand(portage.dep_getkey(mymatch[0]),portage.db["/"]["vartree"].dbapi)
  2369.         if not pkgmap.has_key(mykey):
  2370.             pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] }
  2371.         if unmerge_action=="unmerge":
  2372.                 for y in mymatch:
  2373.                     if y not in pkgmap[mykey]["selected"]:
  2374.                         pkgmap[mykey]["selected"].append(y)
  2375.                         numselected=numselected+len(mymatch)
  2376.  
  2377.         else:
  2378.             #unmerge_action in ["prune", clean"]
  2379.             slotmap={}
  2380.             for mypkg in mymatch:
  2381.                 if unmerge_action=="clean":
  2382.                     myslot=localtree.getslot(mypkg)
  2383.                 else:
  2384.                     #since we're pruning, we don't care about slots and put all the pkgs in together
  2385.                     myslot=0
  2386.                 if not slotmap.has_key(myslot):
  2387.                     slotmap[myslot]={}
  2388.                 slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)]=mypkg
  2389.             for myslot in slotmap.keys():
  2390.                 counterkeys=slotmap[myslot].keys()
  2391.                 counterkeys.sort()
  2392.                 if not counterkeys:
  2393.                     continue
  2394.                 counterkeys.sort()
  2395.                 pkgmap[mykey]["protected"].append(slotmap[myslot][counterkeys[-1]])
  2396.                 del counterkeys[-1]
  2397.                 #be pretty and get them in order of merge:
  2398.                 for ckey in counterkeys:
  2399.                     pkgmap[mykey]["selected"].append(slotmap[myslot][ckey])
  2400.                     numselected=numselected+1
  2401.                 #ok, now the last-merged package is protected, and the rest are selected
  2402.     if global_unmerge and not numselected:
  2403.         print "\n>>> No outdated packages were found on your system.\n"
  2404.         return 0
  2405.  
  2406.     if not numselected:
  2407.         print "\n>>> No packages selected for removal by",unmerge_action+".\n"
  2408.         return 0
  2409.  
  2410.     for x in pkgmap.keys():
  2411.         for y in localtree.dep_match(x):
  2412.             if y not in pkgmap[x]["omitted"] and \
  2413.                y not in pkgmap[x]["selected"] and \
  2414.                y not in pkgmap[x]["protected"]:
  2415.                 pkgmap[x]["omitted"].append(y)
  2416.         if global_unmerge and not pkgmap[x]["selected"]:
  2417.             #avoid cluttering the preview printout with stuff that isn't getting unmerged
  2418.             continue
  2419.         if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and (x in syslist):
  2420.             print red("\a\n\n!!! '%s' is part of your system profile." % x)
  2421.             print yellow("\a!!! Unmerging it may be damaging to your system.\n")
  2422.             if "--pretend" not in myopts and "--ask" not in myopts:
  2423.                 global EMERGE_WARNING_DELAY
  2424.                 countdown(EMERGE_WARNING_DELAY,red("Press Ctrl-C to Stop"))
  2425.         print "\n "+white(x)
  2426.         for mytype in ["selected","protected","omitted"]:
  2427.             print string.rjust(mytype,12)+":",
  2428.             if pkgmap[x][mytype]:
  2429.                 for mypkg in pkgmap[x][mytype]:
  2430.                     mysplit=portage.catpkgsplit(mypkg)
  2431.                     if mysplit[3]=="r0":
  2432.                         myversion=mysplit[2]
  2433.                     else:
  2434.                         myversion=mysplit[2]+"-"+mysplit[3]
  2435.                     if mytype=="selected":
  2436.                         print red(myversion),
  2437.                     else:
  2438.                         print green(myversion),
  2439.             else:
  2440.                     print "none",
  2441.             print
  2442.  
  2443.     if (not "--quiet" in myopts):
  2444.         print "\n>>>",red("'Selected'"),"packages are slated for removal."
  2445.         print ">>>",green("'Protected'"),"and",green("'omitted'"),"packages will not be removed.\n"
  2446.  
  2447.     if "--pretend" in myopts:
  2448.         #we're done... return
  2449.         return 0
  2450.     if "--ask" in myopts:
  2451.         if userquery("Would you like to unmerge these packages?")=="No":
  2452.             # enter pretend mode for correct formatting of results
  2453.             myopts+=["--pretend"]
  2454.             print
  2455.             print "Quitting."
  2456.             print
  2457.             return 0
  2458.     #the real unmerging begins, after a short delay....
  2459.  
  2460.     global CLEAN_DELAY
  2461.     countdown(CLEAN_DELAY, ">>> Unmerging")
  2462.  
  2463.     for x in pkgmap.keys():
  2464.         for y in pkgmap[x]["selected"]:
  2465.             print ">>> Unmerging "+y+"..."
  2466.             emergelog("=== Unmerging... ("+y+")")
  2467.             mysplit=string.split(y,"/")
  2468.             #unmerge...
  2469.             retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,mysettings,unmerge_action not in ["clean","prune"])
  2470.             if retval:
  2471.                 emergelog(" !!! unmerge FAILURE: "+y)
  2472.             else:
  2473.                 emergelog(" >>> unmerge success: "+y)
  2474.     #run ldconfig, etc...
  2475.     portage.env_update()
  2476.     if not numselected:
  2477.         return 0
  2478.     else:
  2479.         return 1
  2480.  
  2481.  
  2482. def chk_updated_info_files(retval):
  2483.     root=portage.root
  2484.  
  2485.     infodirs=[]
  2486.     infodirs.extend(string.split(portage.settings["INFOPATH"], ":"))
  2487.     infodirs.extend(string.split(portage.settings["INFODIR"], ":"))
  2488.  
  2489.     print
  2490.     if os.path.exists("/usr/bin/install-info"):
  2491.         regen_infodirs=[]
  2492.         for z in infodirs:
  2493.             if z=='':
  2494.                 continue
  2495.             inforoot=normpath(root+z)
  2496.             if os.path.isdir(inforoot):
  2497.                 try:
  2498.                     infomtime=os.stat(inforoot)[ST_MTIME]
  2499.                 except SystemExit, e:
  2500.                     raise # Needed else can't exit
  2501.                 except:
  2502.                     infomtime=0
  2503.  
  2504.                 if not portage.mtimedb.has_key("info"):
  2505.                     portage.mtimedb["info"]={}
  2506.                 if portage.mtimedb["info"].has_key(inforoot):
  2507.                     if portage.mtimedb["info"][inforoot]==infomtime:
  2508.                         pass
  2509.                     else:
  2510.                         portage.mtimedb["info"][inforoot]=infomtime
  2511.                         regen_infodirs.append(inforoot)
  2512.                 else:
  2513.                     regen_infodirs.append(inforoot)
  2514.  
  2515.         if not regen_infodirs:
  2516.             print " "+green("*")+" GNU info directory index is up-to-date."
  2517.         else:
  2518.             print " "+green("*")+" Regenerating GNU info directory index..."
  2519.  
  2520.             icount=0
  2521.             badcount=0
  2522.             for inforoot in regen_infodirs:
  2523.                 if inforoot=='':
  2524.                     continue
  2525.                 try:
  2526.                     os.rename(inforoot+"/dir",inforoot+"/dir.old")
  2527.                 except SystemExit, e:
  2528.                     raise # Needed else can't exit
  2529.                 except:
  2530.                     pass
  2531.  
  2532.                 if not os.path.isdir(inforoot):
  2533.                     continue
  2534.                 errmsg = ""
  2535.                 for x in os.listdir(inforoot):
  2536.                     if (x[0] == ".") or (x in ["dir","dir.old"]) or (os.path.isdir(inforoot+"/"+x)):
  2537.                         continue
  2538.                     myso=commands.getstatusoutput("LANG=C LANGUAGE=C /usr/bin/install-info --dir-file="+inforoot+"/dir "+inforoot+"/"+x)[1]
  2539.                     existsstr="already exists, for file `"
  2540.                     if myso!="":
  2541.                         if re.search(existsstr,myso):
  2542.                             # Already exists... Don't increment the count for this.
  2543.                             pass
  2544.                         elif myso[:44]=="install-info: warning: no info dir entry in ":
  2545.                             # This info file doesn't contain a DIR-header: install-info produces this
  2546.                             # (harmless) warning (the --quiet switch doesn't seem to work).
  2547.                             # Don't increment the count for this.
  2548.                             pass
  2549.                         else:
  2550.                             badcount=badcount+1
  2551.                             errmsg += myso + "\n"
  2552.                     icount=icount+1
  2553.  
  2554.                 #update mtime so we can potentially avoid regenerating.
  2555.                 portage.mtimedb["info"][inforoot]=os.stat(inforoot)[ST_MTIME]
  2556.  
  2557.             if badcount:
  2558.                 print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors."
  2559.                 print errmsg
  2560.             else:
  2561.                 print " "+green("*")+" Processed",icount,"info files."
  2562.  
  2563.  
  2564. def post_emerge(retval=0):
  2565.     global myopts
  2566.     os.chdir("/")
  2567.     if "--pretend" in myopts:
  2568.         sys.exit(retval)
  2569.  
  2570.     emergelog(" *** exiting successfully.")
  2571.  
  2572.     if "noinfo" not in portage.settings.features:
  2573.         chk_updated_info_files(retval)
  2574.  
  2575.     chk_updated_cfg_files()
  2576.     sys.exit(retval)
  2577.  
  2578.  
  2579. def chk_updated_cfg_files():
  2580.     if portage.settings["CONFIG_PROTECT"]:
  2581.         #number of directories with some protect files in them
  2582.         procount=0
  2583.         for x in string.split(portage.settings["CONFIG_PROTECT"]):
  2584.             if os.path.isdir(x):
  2585.                 a=commands.getstatusoutput("cd "+x+"; find . -iname '._cfg????_*'")
  2586.                 if a[0]!=0:
  2587.                     print " "+red("*")+" error scanning",x
  2588.                 else:
  2589.                     files=string.split(a[1])
  2590.                     if files:
  2591.                         procount=procount+1
  2592.                         print " "+yellow("* IMPORTANT:")+"",len(files),"config files in",x,"need updating."
  2593.         if procount:
  2594.             #print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
  2595.             print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
  2596.         print
  2597.  
  2598. def is_valid_package_atom(x):
  2599.     testkey = portage.dep_getkey(x)
  2600.     if testkey.startswith("null/"):
  2601.         testatom = x.replace(testkey[5:], "cat/"+testkey[5:])
  2602.     elif "/" not in x:
  2603.         testatom = "cat/"+x
  2604.     else:
  2605.         testatom = x
  2606.     return portage.isvalidatom(testatom)
  2607.  
  2608. def validate_merge_list(mergelist):
  2609.     """Validate the list to make sure all the packages are still available.
  2610.     This is needed for --resume."""
  2611.     for (pkg_type, myroot, pkg_key, action) in mergelist:
  2612.         if pkg_type == "binary" and not portage.db["/"]["bintree"].dbapi.match("="+pkg_key) or \
  2613.             pkg_type == "ebuild" and not portage.db["/"]["porttree"].dbapi.xmatch("match-all", "="+pkg_key):
  2614.             print red("!!! Error: The resume list contains packages that are no longer")
  2615.             print red("!!!        available to be emerged. Please restart/continue")
  2616.             print red("!!!        the merge operation manually.")
  2617.             sys.exit(1)
  2618.  
  2619. # general options that should be taken into account before any action
  2620. if "--debug" in myopts:
  2621.     edebug=1
  2622.  
  2623. if myaction in ["sync","metadata"] and (not "--help" in myopts):
  2624.     if "--pretend" in myopts:
  2625.         print "emerge: \"sync\" actions do not support \"--pretend.\""
  2626.         sys.exit(1)
  2627.  
  2628.     emergelog(" === "+str(myaction))
  2629.     myportdir=portage.settings["PORTDIR"]
  2630.     if myportdir[-1]=="/":
  2631.         myportdir=myportdir[:-1]
  2632.     if not os.path.exists(myportdir):
  2633.         print ">>>",myportdir,"not found, creating it."
  2634.         os.makedirs(myportdir,0755)
  2635.     syncuri=string.rstrip(portage.settings["SYNC"])
  2636.     os.umask(0022)
  2637.     if myaction == "metadata":
  2638.         if "--ask" in myopts:
  2639.             if userquery("Are you sure?") == "No":
  2640.                 sys.exit(1)
  2641.         print "skipping sync"
  2642.         updatecache_flg = True
  2643.         tmpservertimestampfile = None
  2644.     elif syncuri[:8]=="rsync://":
  2645.         if not os.path.exists("/usr/bin/rsync"):
  2646.             print "!!! /usr/bin/rsync does not exist, so rsync support is disabled."
  2647.             print "!!! Type \"emerge net-misc/rsync\" to enable rsync support."
  2648.             sys.exit(1)
  2649.         mytimeout=180
  2650.  
  2651.         rsync_opts = []
  2652.  
  2653.         if portage.settings["PORTAGE_RSYNC_OPTS"] == "":
  2654.             portage.writemsg("PORTAGE_RSYNC_OPTS empty or unset, using hardcoded defaults\n")
  2655.             rsync_opts.extend([
  2656.                 "--recursive",    # Recurse directories
  2657.                 "--links",        # Consider symlinks
  2658.                 "--safe-links",   # Ignore links outside of tree
  2659.                 "--perms",        # Preserve permissions
  2660.                 "--times",        # Preserive mod times
  2661.                 "--compress",     # Compress the data transmitted
  2662.                 "--force",        # Force deletion on non-empty dirs
  2663.                 "--whole-file",   # Don't do block transfers, only entire files
  2664.                 "--delete",       # Delete files that aren't in the master tree
  2665.                 "--delete-after", # Delete only after everything else is done
  2666.                 "--stats",        # Show final statistics about what was transfered
  2667.                 "--timeout="+str(mytimeout), # IO timeout if not done in X seconds
  2668.                 "--exclude='/distfiles'",   # Exclude distfiles from consideration
  2669.                 "--exclude='/local'",       # Exclude local     from consideration
  2670.                 "--exclude='/packages'",    # Exclude packages  from consideration
  2671.             ])
  2672.  
  2673.         else:
  2674.             # The below validation is not needed when using the above hardcoded
  2675.             # defaults.
  2676.  
  2677.             portage.writemsg("Using PORTAGE_RSYNC_OPTS instead of hardcoded defaults\n", 1)
  2678.             rsync_opts.extend(portage.settings["PORTAGE_RSYNC_OPTS"].split())
  2679.  
  2680.             for opt in ("--recursive", "--times"):
  2681.                 if opt not in rsync_opts:
  2682.                     portage.writemsg(yellow("WARNING:") + " adding required option " + \
  2683.                     "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
  2684.                     rsync_opts.append(opt)
  2685.     
  2686.             for exclude in ("distfiles", "local", "packages"):
  2687.                 opt = "--exclude='/%s'" % exclude
  2688.                 if opt not in rsync_opts:
  2689.                     portage.writemsg(yellow("WARNING:") + \
  2690.                     " adding required option %s not included in "  % opt + \
  2691.                     "PORTAGE_RSYNC_OPTS (can be overridden with --exclude='!')\n")
  2692.                     rsync_opts.append(opt)
  2693.     
  2694.             if portage.settings["RSYNC_TIMEOUT"] != "":
  2695.                 portage.writemsg("WARNING: usage of RSYNC_TIMEOUT is deprecated, " + \
  2696.                 "use PORTAGE_RSYNC_EXTRA_OPTS instead\n")
  2697.                 try:
  2698.                     mytimeout = int(portage.settings["RSYNC_TIMEOUT"])
  2699.                     rsync_opts.append("--timeout=%d" % mytimeout)
  2700.                 except ValueError, e:
  2701.                     portage.writemsg("!!! %s\n" % str(e))
  2702.     
  2703.             # TODO: determine options required for official servers
  2704.             if syncuri.rstrip("/").endswith(".gentoo.org/gentoo-portage"):
  2705.  
  2706.                 def rsync_opt_startswith(opt_prefix):
  2707.                     for x in rsync_opts:
  2708.                         if x.startswith(opt_prefix):
  2709.                             return True
  2710.                     return False
  2711.  
  2712.                 if not rsync_opt_startswith("--timeout="):
  2713.                     rsync_opts.append("--timeout=%d" % mytimeout)
  2714.  
  2715.                 for opt in ("--compress", "--whole-file"):
  2716.                     if opt not in rsync_opts:
  2717.                         portage.writemsg(yellow("WARNING:") + " adding required option " + \
  2718.                         "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
  2719.                         rsync_opts.append(opt)
  2720.  
  2721.         if "--quiet" in myopts:
  2722.             rsync_opts.append("--quiet")    # Shut up a lot
  2723.         else:
  2724.             rsync_opts.append("--verbose")    # Print filelist
  2725.  
  2726.         if "--verbose" in myopts:
  2727.             rsync_opts.append("--progress")  # Progress meter for each file
  2728.  
  2729.         if "--debug" in myopts:
  2730.             rsync_opts.append("--checksum") # Force checksum on all files
  2731.  
  2732.         if portage.settings["RSYNC_EXCLUDEFROM"] != "":
  2733.             portage.writemsg(yellow("WARNING:") + \
  2734.             " usage of RSYNC_EXCLUDEFROM is deprecated, use " + \
  2735.             "PORTAGE_RSYNC_EXTRA_OPTS instead\n")
  2736.             if os.path.exists(portage.settings["RSYNC_EXCLUDEFROM"]):
  2737.                 rsync_opts.append("--exclude-from=%s" % \
  2738.                 portage.settings["RSYNC_EXCLUDEFROM"])
  2739.             else:
  2740.                 portage.writemsg("!!! RSYNC_EXCLUDEFROM specified," + \
  2741.                 " but file does not exist.\n")
  2742.  
  2743.         if portage.settings["RSYNC_RATELIMIT"] != "":
  2744.             portage.writemsg(yellow("WARNING:") + \
  2745.             " usage of RSYNC_RATELIMIT is deprecated, use " + \
  2746.             "PORTAGE_RSYNC_EXTRA_OPTS instead")
  2747.             rsync_opts.append("--bwlimit=%s" % \
  2748.             portage.settings["RSYNC_RATELIMIT"])
  2749.  
  2750.         servertimestampdir  = portage.settings.depcachedir+"/"
  2751.         servertimestampfile = portage.settings.depcachedir+"/timestamp.chk"
  2752.         tmpservertimestampdir  = portage.settings["PORTAGE_TMPDIR"]+"/"
  2753.         tmpservertimestampfile = portage.settings["PORTAGE_TMPDIR"]+"/timestamp.chk"
  2754.  
  2755.         # We only use the backup if a timestamp exists in the portdir.
  2756.         content=None
  2757.         if os.path.exists(myportdir+"/metadata/timestamp.chk"):
  2758.             content=portage.grabfile(servertimestampfile)
  2759.         if (not content):
  2760.             content=portage.grabfile(myportdir+"/metadata/timestamp.chk")
  2761.  
  2762.         if (content):
  2763.             try:
  2764.                 mytimestamp=time.mktime(time.strptime(content[0], "%a, %d %b %Y %H:%M:%S +0000"))
  2765.             except ValueError:
  2766.                 mytimestamp=0
  2767.         else:
  2768.             mytimestamp=0
  2769.  
  2770.         if not os.path.exists(servertimestampdir):
  2771.             os.mkdir(servertimestampdir)
  2772.             os.chown(servertimestampdir, os.getuid(), portage.portage_gid)
  2773.             os.chmod(servertimestampdir, 02775)
  2774.  
  2775.         #exitcode=0
  2776.         try:
  2777.             if portage.settings.has_key("RSYNC_RETRIES"):
  2778.                 print yellow("WARNING:")+" usage of RSYNC_RETRIES is deprecated, use PORTAGE_RSYNC_RETRIES instead"
  2779.                 maxretries=int(portage.settings["RSYNC_RETRIES"])                
  2780.             else:
  2781.                 maxretries=int(portage.settings["PORTAGE_RSYNC_RETRIES"])
  2782.         except SystemExit, e:
  2783.             raise # Needed else can't exit
  2784.         except:
  2785.             maxretries=3 #default number of retries
  2786.  
  2787.         retries=0
  2788.         hostname, port=re.split("rsync://([^:/]*)(:[0-9]+)?", syncuri)[1:3];
  2789.         if port is None:
  2790.             port=""
  2791.         updatecache_flg=True
  2792.  
  2793.         ips=[]
  2794.         while (1):
  2795.             if ips:
  2796.                 del ips[0]
  2797.             if ips==[]:
  2798.                 try:
  2799.                     ips=socket.gethostbyname_ex(hostname)[2]
  2800.                 except SystemExit, e:
  2801.                     raise # Needed else can't exit
  2802.                 except Exception, e:
  2803.                     print "Notice:",str(e)
  2804.                     dosyncuri=syncuri
  2805.  
  2806.             if ips:
  2807.                 try:
  2808.                     dosyncuri=string.replace(syncuri, "//"+hostname+port+"/", "//"+ips[0]+port+"/", 1)
  2809.                 except SystemExit, e:
  2810.                     raise # Needed else can't exit
  2811.                 except Exception, e:
  2812.                     print "Notice:",str(e)
  2813.                     dosyncuri=syncuri
  2814.  
  2815.             if (retries==0):
  2816.                 if "--ask" in myopts:
  2817.                     if userquery("Do you want to sync your Portage tree with the mirror at\n" + blue(dosyncuri) + bold("?"))=="No":
  2818.                         print
  2819.                         print "Quitting."
  2820.                         print
  2821.                         sys.exit(0)
  2822.                 emergelog(">>> Starting rsync with "+dosyncuri)
  2823.                 if "--quiet" not in myopts:
  2824.                     print ">>> Starting rsync with "+dosyncuri+"..."
  2825.             else:
  2826.                 emergelog(">>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri))
  2827.                 print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri)
  2828.  
  2829.             if "--quiet" not in myopts:
  2830.                 print ">>> Checking server timestamp ..."
  2831.  
  2832.             rsynccommand = " ".join(["/usr/bin/rsync",
  2833.                 portage.settings["PORTAGE_RSYNC_EXTRA_OPTS"],
  2834.                 " ".join(rsync_opts)])
  2835.  
  2836.             if "--debug" in myopts:
  2837.                 print rsynccommand
  2838.  
  2839.             mycommand = " ".join([rsynccommand,
  2840.                 dosyncuri + "/metadata/timestamp.chk",
  2841.                 tmpservertimestampdir])
  2842.             exitcode=portage.spawn(mycommand,portage.settings,free=1)
  2843.             if (exitcode==0):
  2844.                 try:
  2845.                     servertimestamp = time.mktime(time.strptime(portage.grabfile(tmpservertimestampfile)[0], "%a, %d %b %Y %H:%M:%S +0000"))
  2846.                 except SystemExit, e:
  2847.                     raise # Needed else can't exit
  2848.                 except:
  2849.                     servertimestamp = 0
  2850.  
  2851.                 if (servertimestamp != 0) and (servertimestamp == mytimestamp):
  2852.                     emergelog(">>> Cancelling sync -- Already current.")
  2853.                     print
  2854.                     print ">>>"
  2855.                     print ">>> Timestamps on the server and in the local repository are the same."
  2856.                     print ">>> Cancelling all further sync action. You are already up to date."
  2857.                     print ">>>"
  2858.                     print
  2859.                     sys.exit(0)
  2860.                 elif (servertimestamp != 0) and (servertimestamp < mytimestamp):
  2861.                     emergelog(">>> Server out of date: %s" % dosyncuri)
  2862.                     print
  2863.                     print ">>>"
  2864.                     print ">>> SERVER OUT OF DATE: %s" % dosyncuri
  2865.                     print ">>>"
  2866.                     print
  2867.                 elif (servertimestamp == 0) or (servertimestamp > mytimestamp):
  2868.                     # actual sync
  2869.                     mycommand=rsynccommand+" "+dosyncuri+"/ "+myportdir
  2870.                     exitcode=portage.spawn(mycommand,portage.settings,free=1)
  2871.                     if exitcode in [0,1,2,3,4,11,14,20,21]:
  2872.                         break
  2873.             elif exitcode in [0,1,2,3,4,11,14,20,21]:
  2874.                 break
  2875.  
  2876.             retries=retries+1
  2877.  
  2878.             if retries<=maxretries:
  2879.                 print ">>> Retrying..."
  2880.                 time.sleep(11)
  2881.             else:
  2882.                 # over retries
  2883.                 # exit loop
  2884.                 updatecache_flg=False
  2885.                 break
  2886.  
  2887.         if (exitcode==0):
  2888.             emergelog("=== Sync completed with %s" % dosyncuri)
  2889.             # save timestamp.chk for next timestamp check.
  2890.             try:
  2891.                 if tmpservertimestampfile is not None:
  2892.                     portage.movefile(tmpservertimestampfile,
  2893.                         servertimestampfile)
  2894.             except SystemExit, e:
  2895.                 raise
  2896.             except Exception, e:
  2897.                 portage.writemsg("!!! Failed to save current timestamp.\n",
  2898.                     noiselevel=-1)
  2899.                 portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
  2900.                 del e
  2901.         elif (exitcode>0):
  2902.             print
  2903.             if exitcode==1:
  2904.                 print darkred("!!!")+green(" Rsync has reported that there is a syntax error. Please ensure")
  2905.                 print darkred("!!!")+green(" that your SYNC statement is proper.")
  2906.                 print darkred("!!!")+green(" SYNC="+portage.settings["SYNC"])
  2907.             elif exitcode==11:
  2908.                 print darkred("!!!")+green(" Rsync has reported that there is a File IO error. Normally")
  2909.                 print darkred("!!!")+green(" this means your disk is full, but can be caused by corruption")
  2910.                 print darkred("!!!")+green(" on the filesystem that contains PORTDIR. Please investigate")
  2911.                 print darkred("!!!")+green(" and try again after the problem has been fixed.")
  2912.                 print darkred("!!!")+green(" PORTDIR="+portage.settings["PORTDIR"])
  2913.             elif exitcode==20:
  2914.                 print darkred("!!!")+green(" Rsync was killed before it finished.")
  2915.             else:
  2916.                 print darkred("!!!")+green(" Rsync has not successfully finished. It is recommended that you keep")
  2917.                 print darkred("!!!")+green(" trying or that you use the 'emerge-webrsync' option if you are unable")
  2918.                 print darkred("!!!")+green(" to use rsync due to firewall or other restrictions. This should be a")
  2919.                 print darkred("!!!")+green(" temporary problem unless complications exist with your network")
  2920.                 print darkred("!!!")+green(" (and possibly your system's filesystem) configuration.")
  2921.             print
  2922.             sys.exit(exitcode)
  2923.     elif syncuri[:6]=="cvs://":
  2924.         if not os.path.exists("/usr/bin/cvs"):
  2925.             print "!!! /usr/bin/cvs does not exist, so CVS support is disabled."
  2926.             print "!!! Type \"emerge dev-util/cvs\" to enable CVS support."
  2927.             sys.exit(1)
  2928.         cvsroot=syncuri[6:]
  2929.         cvsdir=os.path.dirname(myportdir)
  2930.         if not os.path.exists(myportdir+"/CVS"):
  2931.             #initial checkout
  2932.             print ">>> Starting initial cvs checkout with "+syncuri+"..."
  2933.             if os.path.exists(cvsdir+"/gentoo-x86"):
  2934.                 print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting."
  2935.                 sys.exit(1)
  2936.             if portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co -P gentoo-x86",portage.settings,free=1):
  2937.                 print "!!! cvs checkout error; exiting."
  2938.                 sys.exit(1)
  2939.             if cvsdir!=myportdir:
  2940.                 portage.movefile(cvsdir,portage.settings["PORTDIR"])
  2941.             sys.exit(0)
  2942.         else:
  2943.             #cvs update
  2944.             print ">>> Starting cvs update with "+syncuri+"..."
  2945.             sys.exit(portage.spawn("cd "+myportdir+"; cvs -z0 -q update -dP",portage.settings,free=1))
  2946.     else:
  2947.         print "!!! rsync setting: ",syncuri,"not recognized; exiting."
  2948.         sys.exit(1)
  2949.  
  2950.     if updatecache_flg and  \
  2951.         myaction != "metadata" and \
  2952.         "metadata-transfer" not in portage.settings.features:
  2953.         updatecache_flg = False
  2954.  
  2955.     if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg:
  2956.         if "--quiet" not in myopts:
  2957.             print "\n>>> Updating Portage cache:      ",
  2958.         os.umask(0002)
  2959.         cachedir = os.path.normpath(portage.settings.depcachedir)
  2960.         if cachedir in ["/",    "/bin", "/dev",  "/etc",  "/home",
  2961.                         "/lib", "/opt", "/proc", "/root", "/sbin",
  2962.                         "/sys", "/tmp", "/usr",  "/var"]:
  2963.             print "!!! PORTAGE_CACHEDIR IS SET TO A PRIMARY ROOT DIRECTORY ON YOUR SYSTEM."
  2964.             print "!!! This is ALMOST CERTAINLY NOT what you want: "+str(cachedir)
  2965.             sys.exit(73)
  2966.         if not os.path.exists(cachedir):
  2967.             os.mkdir(cachedir)
  2968.  
  2969.         # Potentially bad
  2970.         #if os.path.exists(cachedir+"/"+myportdir):
  2971.         #    portage.spawn("rm -Rf "+cachedir+"/"+myportdir+"/*",portage.settings,free=1)
  2972.  
  2973.         portage.portdb.flush_cache()
  2974.  
  2975.         ec = portage.eclass_cache.cache(portage.portdb.porttree_root)
  2976.         # kinda ugly.
  2977.         # XXX: nuke the filter when mr UNUSED_0? keys are dead
  2978.         cm = portage.settings.load_best_module("portdbapi.metadbmodule")(myportdir, "metadata/cache", 
  2979.             filter(lambda x: not x.startswith("UNUSED_0"), portage.auxdbkeys))
  2980.  
  2981.         # we don't make overlay trees cache here, plus we don't trust portage.settings.categories
  2982.         porttree_root = portage.portdb.porttree_root
  2983.         conf = portage.config(config_profile_path=portage.settings.profile_path[:], \
  2984.             config_incrementals=portage.settings.incrementals[:])
  2985.  
  2986.         conf["PORTDIR_OVERLAY"] = ''
  2987.         conf.categories = portage.grabfile(os.path.join(porttree_root, "profiles", "categories"))
  2988.         try:
  2989.             i = conf.categories.index("virtual")
  2990.             if i != -1:
  2991.                 conf.categories.remove(i)
  2992.         except (ValueError, IndexError):
  2993.             pass
  2994.  
  2995.         pdb = portage.portdbapi(porttree_root, conf)
  2996.  
  2997.         cp_all_list = pdb.cp_all()
  2998.         import cache.util
  2999.  
  3000.         class percentage_noise_maker(cache.util.quiet_mirroring):
  3001.             def __init__(self, dbapi):
  3002.                 self.dbapi = dbapi
  3003.                 self.cp_all = dbapi.cp_all()
  3004.                 l = len(self.cp_all)
  3005.                 self.call_update_min = 100000000
  3006.                 self.min_cp_all = l/100.0
  3007.                 self.count = 1
  3008.                 self.pstr = ''
  3009.  
  3010.             def __iter__(self):
  3011.                 for x in self.cp_all:
  3012.                     self.count += 1
  3013.                     if self.count > self.min_cp_all:
  3014.                         self.call_update_min = 0
  3015.                         self.count = 0
  3016.                     for y in self.dbapi.cp_list(x):
  3017.                         yield y
  3018.                 self.call_update_mine = 0
  3019.  
  3020.             def update(self, *arg):
  3021.                 try:                self.pstr = int(self.pstr) + 1
  3022.                 except ValueError:    self.pstr = 1
  3023.                 sys.stdout.write("%s%i%%" % ("\b" * (len(str(self.pstr))+1), self.pstr))
  3024.                 sys.stdout.flush()
  3025.                 self.call_update_min = 10000000
  3026.  
  3027.             def finish(self, *arg):
  3028.                 sys.stdout.write("\b\b\b\b100%\n")
  3029.                 sys.stdout.flush()
  3030.  
  3031.  
  3032.         if "--quiet" in myopts:
  3033.             def quicky_cpv_generator(cp_all_list):
  3034.                 for x in cp_all_list:
  3035.                     for y in pdb.cp_list(x):
  3036.                         yield y
  3037.             source = quicky_cpv_generator(pdb.cp_all())
  3038.             noise_maker = cache.util.quiet_mirroring()
  3039.         else:
  3040.             noise_maker = source = percentage_noise_maker(pdb)
  3041.         cache.util.mirror_cache(source, cm, pdb.auxdb[porttree_root], eclass_cache=ec, verbose_instance=noise_maker)
  3042.  
  3043.         sys.stdout.flush()
  3044.  
  3045.     portage.portageexit()
  3046.     reload(portage)
  3047.     portage.global_updates(
  3048.         portage.settings, portage.db, portage.mtimedb["updates"])
  3049.     mybestpv=portage.portdb.xmatch("bestmatch-visible","sys-apps/portage")
  3050.     mypvs=portage.best(portage.db[portage.root]["vartree"].dbapi.match("sys-apps/portage"))
  3051.  
  3052.     chk_updated_cfg_files()
  3053.  
  3054.     if myaction != "metadata":
  3055.         if os.access(portage.USER_CONFIG_PATH + "/bin/post_sync", os.X_OK):
  3056.             try:
  3057.                 portage.spawn(portage.USER_CONFIG_PATH + "/bin/post_sync " + dosyncuri, portage.settings, free=1)
  3058.             except:
  3059.                 print red(" * ")+bold("spawn failed of "+ portage.USER_CONFIG_PATH + "/bin/post_sync")
  3060.  
  3061.     if(mybestpv != mypvs) and not "--quiet" in myopts:
  3062.         print
  3063.         print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended"
  3064.         print red(" * ")+"that you update portage now, before any other packages are updated."
  3065.         print red(" * ")+"Please run 'emerge portage' and then update "+bold("ALL")+" of your"
  3066.         print red(" * ")+"configuration files."
  3067.         print red(" * ")+"To update portage, run 'emerge portage'."
  3068.         print
  3069. elif myaction=="regen":
  3070.     emergelog(" === regen")
  3071.     #regenerate cache entries
  3072.     print "Regenerating cache entries... "
  3073.     try:
  3074.         os.close(sys.stdin.fileno())
  3075.     except SystemExit, e:
  3076.         raise # Needed else can't exit
  3077.     except:
  3078.         pass
  3079.     sys.stdout.flush()
  3080.     mynodes=portage.portdb.cp_all()
  3081.     for x in mynodes:
  3082.         mymatches=portage.portdb.xmatch("match-all",x)
  3083.         if not "--quiet" in myopts:
  3084.             print "processing",x
  3085.         for y in mymatches:
  3086.             try:
  3087.                 foo=portage.portdb.aux_get(y,["DEPEND"])
  3088.             except SystemExit, e:
  3089.                 # sys.exit is an exception... And consequently, we can't catch it.
  3090.                 raise
  3091.             except Exception, e:
  3092.                 print "\n  error processing %(cpv)s, continuing... (%(e)s)" % {"cpv":y,"e":str(e)}
  3093.     print "done!"
  3094. # HELP action
  3095. elif "config"==myaction:
  3096.     if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
  3097.         print red("!!! config can only take a single package atom at this time\n")
  3098.         sys.exit(1)
  3099.     if not is_valid_package_atom(myfiles[0]):
  3100.         portage.writemsg("!!! '%s' is not a valid package atom.\n" % myfiles[0],
  3101.             noiselevel=-1)
  3102.         portage.writemsg("!!! Please check ebuild(5) for full details.\n")
  3103.         portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
  3104.         sys.exit(1)
  3105.     print
  3106.     try:
  3107.         pkgs = portage.db[portage.root]["vartree"].dbapi.match(myfiles[0])
  3108.     except ValueError, e:
  3109.         # Multiple matches thrown from cpv_expand
  3110.         pkgs = e.args[0]
  3111.     if len(pkgs) == 0:
  3112.         print "No packages found.\n"
  3113.         sys.exit(0)
  3114.     elif len(pkgs) > 1:
  3115.         if "--ask" in myopts:
  3116.             options = []
  3117.             print "Please select a package to configure:"
  3118.             idx = 0
  3119.             for pkg in pkgs:
  3120.                 idx += 1
  3121.                 options.append(str(idx))
  3122.                 print options[-1]+") "+pkg
  3123.             print "X) Cancel"
  3124.             options.append("X")
  3125.             idx = userquery("Selection?", options)
  3126.             if idx == "X":
  3127.                 sys.exit(0)
  3128.             pkg = pkgs[int(idx)-1]
  3129.         else:
  3130.             print "The following packages available:"
  3131.             for pkg in pkgs:
  3132.                 print "* "+pkg
  3133.             print "\nPlease use a specific atom or the --ask option."
  3134.             sys.exit(1)
  3135.     else:
  3136.         pkg = pkgs[0]
  3137.  
  3138.     print
  3139.     if "--ask" in myopts:
  3140.         if userquery("Ready to configure "+pkg+"?") == "No":
  3141.             sys.exit(0)
  3142.     else:
  3143.         print "Configuring pkg..."
  3144.     print
  3145.     ebuildpath = portage.db[portage.root]["vartree"].dbapi.findname(pkg)
  3146.     mysettings = portage.config(clone=portage.settings)
  3147.     portage.doebuild(ebuildpath,"config",portage.root,mysettings,debug=("--debug" in myopts),cleanup=True,tree="vartree")
  3148.     print
  3149.  
  3150. # INFO action
  3151. elif "info"==myaction:
  3152.     unameout=commands.getstatusoutput("uname -mrp")[1]
  3153.     print getportageversion()
  3154.     print "================================================================="
  3155.     print "System uname: "+unameout
  3156.     if os.path.exists("/etc/gentoo-release"):
  3157.         os.system("cat /etc/gentoo-release")
  3158.     else:
  3159.         print "Unknown Host Operating System"
  3160.  
  3161.     output=commands.getstatusoutput("distcc --version")
  3162.     if not output[0]:
  3163.         print str(string.split(output[1],"\n",1)[0]),
  3164.         if "distcc" in portage.settings.features:
  3165.             print "[enabled]"
  3166.         else:
  3167.             print "[disabled]"
  3168.  
  3169.     output=commands.getstatusoutput("ccache -V")
  3170.     if not output[0]:
  3171.         print str(string.split(output[1],"\n",1)[0]),
  3172.         if "ccache" in portage.settings.features:
  3173.             print "[enabled]"
  3174.         else:
  3175.             print "[disabled]"
  3176.  
  3177.     myvars  = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers",
  3178.                "sys-devel/binutils", "sys-devel/libtool",  "dev-lang/python"]
  3179.     myvars += portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_pkgs")
  3180.     myvars  = portage_util.unique_array(myvars)
  3181.     myvars.sort()
  3182.  
  3183.     for x in myvars:
  3184.         if portage.isvalidatom(x):
  3185.             pkg_matches = portage.db["/"]["vartree"].dbapi.match(x)
  3186.             pkgs = []
  3187.             for y in pkg_matches:
  3188.                 mycpv   = portage.catpkgsplit(y)
  3189.                 if(mycpv[3] != "r0"):
  3190.                     pkgs += [mycpv[2] + "-" + mycpv[3]]
  3191.                 else:
  3192.                     pkgs += [mycpv[2]]
  3193.             if not pkgs:
  3194.                 pkgs = "[Not Present]"
  3195.             else:
  3196.                 pkgs = ", ".join(sorted_versions(pkgs))
  3197.             print "%-20s %s" % (x+":", pkgs)
  3198.         else:
  3199.             print "%-20s %s" % (x+":", "[NOT VALID]")
  3200.  
  3201.     libtool_vers = string.join(portage.db["/"]["vartree"].dbapi.match("sys-devel/libtool"), ",")
  3202.  
  3203.     if "--verbose" in myopts:
  3204.         myvars=portage.settings.keys()
  3205.     else:
  3206.         myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK',
  3207.                   'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR',
  3208.                   'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS',
  3209.                   'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES', 'EMERGE_DEFAULT_OPTS']
  3210.  
  3211.         myvars.extend(portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_vars"))
  3212.  
  3213.     myvars = portage_util.unique_array(myvars)
  3214.     unset_vars = []
  3215.     myvars.sort()
  3216.     for x in myvars:
  3217.         if portage.settings.has_key(x):
  3218.             print x+'="'+portage.settings[x]+'"'
  3219.         else:
  3220.             unset_vars.append(x)
  3221.     if unset_vars:
  3222.         print "Unset:  "+", ".join(unset_vars)
  3223.     print
  3224.  
  3225.     if "--debug" in myopts:
  3226.         for x in dir(portage):
  3227.             module = getattr(portage, x)
  3228.             if "cvs_id_string" in dir(module):
  3229.                 print "%s: %s" % (str(x), str(module.cvs_id_string))
  3230.  
  3231. # SEARCH action
  3232. elif "search"==myaction:
  3233.     if not myfiles:
  3234.         print "emerge: no search terms provided."
  3235.     else:
  3236.         searchinstance = search()
  3237.         for mysearch in myfiles:
  3238.             try:
  3239.                 searchinstance.execute(mysearch)
  3240.             except re.error, comment:
  3241.                 print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment )
  3242.                 sys.exit(1)
  3243.             searchinstance.output()
  3244. elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction:
  3245.     if 1 == unmerge(myaction, myfiles, raise_on_missing=False):
  3246.         post_emerge()
  3247.  
  3248. elif "depclean"==myaction:
  3249.     # Kill packages that aren't explicitly merged or are required as a
  3250.     # dependency of another package. World file is explicit.
  3251.  
  3252.     print
  3253.     print red("*** WARNING ***")+"  --depclean is known to be broken. It is highly recommended"
  3254.     print red("*** WARNING ***")+"  that "+green("`emerge --update --newuse --deep world`")+" be ran before"
  3255.     print red("*** WARNING ***")+"  commencing. However, using --depclean may still break link"
  3256.     print red("*** WARNING ***")+"  level consistency within your system. "+green("`revdep-rebuild`")
  3257.     print red("*** WARNING ***")+"  from app-portage/gentoolkit can help to detect breakage."
  3258.     print red("*** WARNING ***")
  3259.     print red("*** WARNING ***")+"  Also study the list of packages to be cleaned for any"
  3260.     print red("*** WARNING ***")+"  obvious mistakes. Packages can be manually added to the"
  3261.     print red("*** WARNING ***")+"  world list by running "+green("`emerge --noreplace <atom>`")+"."
  3262.     print red("*** WARNING ***")
  3263.     print red("*** WARNING ***")+"  It is normal for packages that are masked or listed in"
  3264.     print red("*** WARNING ***")+"  package.provided to be removed by depclean.  These are the most"
  3265.     print red("*** WARNING ***")+"  likely reasons that depclean will remove a package even though"
  3266.     print red("*** WARNING ***")+"  it is in the world or system package set.  In order to"
  3267.     print red("*** WARNING ***")+"  troubleshoot these types of problems, it is often helpful to"
  3268.     print red("*** WARNING ***")+"  look at the output of "+green("`grep -r <atom> /etc/portage`")+"."
  3269.     print red("*** WARNING ***")
  3270.     print red("*** WARNING ***")+"  "+bold("Make sure you have a backup.")
  3271.  
  3272.     syslist=getlist("system")
  3273.     worldlist=getlist("world")
  3274.     myvarlist=portage.vardbapi(portage.root).cp_all()
  3275.  
  3276.     if not syslist:
  3277.         print "\n!!! You have no system list.",
  3278.     if not worldlist:
  3279.         print "\n!!! You have no world file.",
  3280.     if not myvarlist:
  3281.         print "\n!!! You have no installed package database (%s)." % portage.VDB_PATH,
  3282.  
  3283.     if not (syslist and worldlist and myvarlist):
  3284.         print "\n!!! Proceeding will break your installation.\n"
  3285.         countdown(EMERGE_WARNING_DELAY, ">>> Depclean")
  3286.  
  3287.     if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
  3288.         emergelog(" >>> depclean")
  3289.     
  3290.     mydepgraph=depgraph(myaction,myopts)
  3291.  
  3292.     if not ("--quiet" in myopts):
  3293.         print "\nCalculating dependencies  ",
  3294.     if not mydepgraph.xcreate("world"):
  3295.         print "\n!!! Failed to create deptree."
  3296.         sys.exit(1)
  3297.     if not ("--quiet" in myopts):
  3298.         print "\b\b... done!"
  3299.  
  3300.     if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
  3301.         sys.stderr.write(red("The following binaries are not available for merging...\n"))
  3302.         for x in mydepgraph.missingbins:
  3303.             sys.stderr.write("   "+str(x)+"\n")
  3304.         sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
  3305.         sys.exit(1)
  3306.  
  3307.     alldeps=mydepgraph.digraph.allnodes()
  3308.  
  3309.     if not alldeps:
  3310.         print "!!! You have no dependencies. Impossible. Bug."
  3311.         sys.exit(1)
  3312.  
  3313.     reallist=[]
  3314.     for x in alldeps:
  3315.         myparts=portage.catpkgsplit(string.split(x)[2])
  3316.         if not myparts:
  3317.             sys.stderr.write(
  3318.               red("!!! There appears to be a problem with the following package:\n")+
  3319.                 red("!!! "+str(string.split(x)[2])+"\n\n")+
  3320.                     "!!! Please ensure that blocking/conflicting packages are not merged."+
  3321.                         "!!! 'emerge -p "+str(string.split(x)[2])+"\n\n")
  3322.             if ("--pretend" not in myopts) and ("--ask" not in myopts):
  3323.                 countdown(EMERGE_WARNING_DELAY, "*** Continuing")
  3324.             continue
  3325.  
  3326.         catpack=myparts[0]+"/"+myparts[1]
  3327.         if catpack not in reallist:
  3328.             reallist.append(catpack)
  3329.  
  3330.     cleanlist=[]
  3331.     for x in myvarlist:
  3332.         if x not in reallist:
  3333.             if x not in cleanlist:
  3334.                 cleanlist.append(x)
  3335.  
  3336.     for x in syslist+worldlist:
  3337.         myparts = portage.catpkgsplit(x)
  3338.         if myparts:
  3339.             if myparts[0][0] in ('<','>','='):
  3340.                 myparts[0] = myparts[0][1:]
  3341.             if myparts[0][0] in ('<','>','='):
  3342.                 myparts[0] = myparts[0][1:]
  3343.             catpack=myparts[0]+"/"+myparts[1]
  3344.         else:
  3345.             catpack=x
  3346.         if catpack in cleanlist:
  3347.             cleanlist.remove(catpack)
  3348.  
  3349.     #print "\n\n\nCleaning: "
  3350.     #for x in cleanlist:
  3351.     #    print x
  3352.     #print
  3353.  
  3354.     if len(cleanlist):
  3355.         unmerge("unmerge", cleanlist)
  3356.  
  3357.     print
  3358.     print "Packages installed:   "+str(len(myvarlist))
  3359.     print "Packages in world:    "+str(len(worldlist))
  3360.     print "Packages in system:   "+str(len(syslist))
  3361.     print "Unique package names: "+str(len(reallist))
  3362.     print "Required packages:    "+str(len(alldeps))
  3363.     if "--pretend" in myopts:
  3364.         print "Number to remove:     "+str(len(cleanlist))
  3365.     else:
  3366.         print "Number removed:       "+str(len(cleanlist))
  3367.         post_emerge()
  3368.  
  3369. # "update", "system", or just process files:
  3370. else:
  3371.     favorites=[]
  3372.     syslist=getlist("system")
  3373.     if ("--ask" in myopts or "--pretend" in myopts) and not "--quiet" in myopts:
  3374.         action = ""
  3375.         if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
  3376.             action = "fetched"
  3377.         else:
  3378.             action = "merged"
  3379.         if "--tree" in myopts and action != "fetched": # Tree doesn't work with fetching
  3380.             print
  3381.             print darkgreen("These are the packages that would be %s, in reverse order:") % action
  3382.             print
  3383.         else:
  3384.             print
  3385.             print darkgreen("These are the packages that would be %s, in order:") % action
  3386.             print
  3387.  
  3388.     if "--resume" in myopts and \
  3389.         ("resume" in portage.mtimedb or
  3390.         "resume_backup" in portage.mtimedb):
  3391.         if "resume" not in portage.mtimedb:
  3392.             portage.mtimedb["resume"] = portage.mtimedb["resume_backup"]
  3393.             del portage.mtimedb["resume_backup"]
  3394.             portage.commit_mtimedb()
  3395.         myresumeopts=portage.mtimedb["resume"]["myopts"][:]
  3396.  
  3397.         for opt in ("--skipfirst", "--ask", "--tree"):
  3398.             while opt in myresumeopts:
  3399.                 myresumeopts.remove(opt)
  3400.  
  3401.         for myopt in myopts:
  3402.             if myopt not in myresumeopts:
  3403.                 myresumeopts.append(myopt)
  3404.         myopts=myresumeopts
  3405.         mydepgraph=depgraph("resume",myopts)
  3406.         if "--resume" not in myopts:
  3407.             myopts+=["--resume"]
  3408.     else:
  3409.         if ("--resume" in myopts):
  3410.             del myopts[myopts.index("--resume")]
  3411.             print darkgreen("emerge: It seems we have nothing to resume...")
  3412.             sys.exit(0)
  3413.  
  3414.         mydepgraph=depgraph(myaction,myopts)
  3415.         if myaction in ["system","world"]:
  3416.             if not ("--quiet" in myopts):
  3417.                 print "Calculating",myaction,"dependencies  ",
  3418.                 sys.stdout.flush()
  3419.             if not mydepgraph.xcreate(myaction):
  3420.                 print "!!! Depgraph creation failed."
  3421.                 sys.exit(1)
  3422.             if not ("--quiet" in myopts):
  3423.                 print "\b\b... done!"
  3424.         else:
  3425.             if not ("--quiet" in myopts):
  3426.                 print "Calculating dependencies  ",
  3427.                 sys.stdout.flush()
  3428.             try:
  3429.                 retval, favorites = mydepgraph.select_files(myfiles)
  3430.             except portage_exception.PackageNotFound, e:
  3431.                 portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1)
  3432.                 sys.exit(1)
  3433.             if not retval:
  3434.                 sys.exit(1)
  3435.             if not ("--quiet" in myopts):
  3436.                 print "\b\b... done!"
  3437.  
  3438.             if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
  3439.                 sys.stderr.write(red("The following binaries are not available for merging...\n"))
  3440.  
  3441.         if mydepgraph.missingbins:
  3442.             for x in mydepgraph.missingbins:
  3443.                 sys.stderr.write("   "+str(x)+"\n")
  3444.             sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
  3445.             sys.exit(1)
  3446.  
  3447.     if "--ask" in myopts:
  3448.         if "--resume" in myopts:
  3449.             validate_merge_list(portage.mtimedb["resume"]["mergelist"])
  3450.             mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
  3451.             prompt="Would you like to resume merging these packages?"
  3452.         else:
  3453.             mydepgraph.display(mydepgraph.altlist())
  3454.             mergecount=0
  3455.             for x in mydepgraph.altlist():
  3456.                 if x[3]!="nomerge":
  3457.                     mergecount+=1
  3458.                 #check for blocking dependencies
  3459.                 if x[0]=="blocks" and "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts:
  3460.                     print "\n!!! Error: The above package list contains packages which cannot be installed"
  3461.                     print   "!!!        at the same time on the same system."
  3462.                     print
  3463.                     sys.exit(1)
  3464.             if mergecount==0:
  3465.                 if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
  3466.                     prompt="Nothing to merge; would you like to auto-clean packages?"
  3467.                 else:
  3468.                     print
  3469.                     print "Nothing to merge; quitting."
  3470.                     print
  3471.                     sys.exit(0)
  3472.             elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
  3473.                 prompt="Would you like to fetch the source files for these packages?"
  3474.             else:
  3475.                 prompt="Would you like to merge these packages?"
  3476.         print
  3477.         if userquery(prompt)=="No":
  3478.             print
  3479.             print "Quitting."
  3480.             print
  3481.             sys.exit(0)
  3482.         # Don't ask again (e.g. when auto-cleaning packages after merge)
  3483.         myopts.remove("--ask")
  3484.  
  3485.     if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
  3486.         if ("--resume" in myopts):
  3487.             validate_merge_list(portage.mtimedb["resume"]["mergelist"])
  3488.             mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
  3489.         else:
  3490.             mydepgraph.display(mydepgraph.altlist())
  3491.     else:
  3492.         if ("--buildpkgonly" in myopts):
  3493.             if not mydepgraph.digraph.hasallzeros():
  3494.                 print "\n!!! --buildpkgonly requires all dependencies to be merged."
  3495.                 print "!!! Cannot merge requested packages. Merge deps and try again.\n"
  3496.                 sys.exit(1)
  3497.  
  3498.         if ("--resume" in myopts):
  3499.             favorites=portage.mtimedb["resume"]["favorites"]
  3500.             mydepgraph.merge(portage.mtimedb["resume"]["mergelist"])
  3501.         else:
  3502.             if "resume" in portage.mtimedb and \
  3503.             "mergelist" in portage.mtimedb["resume"] and \
  3504.             len(portage.mtimedb["resume"]["mergelist"]) > 1:
  3505.                 portage.mtimedb["resume_backup"] = portage.mtimedb["resume"]
  3506.                 del portage.mtimedb["resume"]
  3507.                 portage.commit_mtimedb()
  3508.             portage.mtimedb["resume"]={}
  3509.             portage.mtimedb["resume"]["myopts"]=myopts
  3510.             portage.mtimedb["resume"]["favorites"]=favorites
  3511.             if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
  3512.                 for pkgline in mydepgraph.altlist():
  3513.                     if pkgline[0]=="ebuild" and pkgline[3]=="merge":
  3514.                         y=portage.portdb.findname(pkgline[2])
  3515.                         tmpsettings = portage.config(clone=portage.settings)
  3516.                         retval=portage.doebuild(y,"digest",portage.root,tmpsettings,edebug,("--pretend" in myopts),tree="porttree")
  3517.             if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
  3518.                 pkglist = []
  3519.                 for pkg in mydepgraph.altlist():
  3520.                     if pkg[0] != "blocks":
  3521.                         pkglist.append(pkg)
  3522.             else:
  3523.                 pkglist = mydepgraph.altlist()
  3524.             mydepgraph.merge(pkglist)
  3525.  
  3526.         if portage.mtimedb.has_key("resume"):
  3527.             del portage.mtimedb["resume"]
  3528.         if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
  3529.             print ">>> Auto-cleaning packages..."
  3530.             unmerge("clean", ["world"])
  3531.         else:
  3532.             portage.writemsg_stdout(colorize("WARN", "WARNING:")
  3533.                 + " AUTOCLEAN is disabled.  This can cause serious"
  3534.                 + " problems due to overlapping packages.\n")
  3535.     post_emerge()
  3536.